feed.nvim

Commands

Sub commands and arguments

To execute actions available in the current context, or give arguments to the command, use the following syntax:

Use :Feed <Tab>, :Feed update_feed <Tab> to get the completion

Use :Feed<Enter>, :Feed update_feed<Enter> to open menu and select

List of commands

name desc bang
Feed <query> opens a index buffer, a list view based on the filter you passed in no
Feed index opens a index buffer, a list view based on your default filter no
Feed entry opens a entry buffer, a markdown view of the entry content no
Feed update updates all feeds in the database no
Feed update_feed <feed_url> update a single feed in the database no
Feed sync sync the database with your config, removes feeds and entries (if bang) not present yes
Feed search <query> opens picker to live search your database no
Feed grep opens picker to live grep your database (experimental) no
Feed list opens a split to show info about all your feeds in database no
Feed log opens a split to show log no
Feed load_opml <filepath/url> import from an OPML file or url no
Feed export_opml <filepath> export to an OPML file no
Feed web <port> opens a server on a port and opens the web interface in browser no
Feed urlview opens a select UI to picker urls in entry buffer, to open in browser no

Keymaps

By default, feed.nvim will not set any keymaps for you, press ? in to see buffer-local keymaps.

Index buffer

action key
hints ?
dot_repeat .
undo u
redo <C-r>
entry <CR>
split <M-CR>
browser b
refresh r
update R
search s
yank_url Y
untag -
tag +
quit q

Entry buffer

action key
hints ?
browser b
next }
prev {
full f
search s
untag -
tag +
urlview r
yank_url Y
quit q

Manage

From lua

Pass your feeds as list of links and tags in setup

Use Feed update to update all

Use Feed update_feed to update one feed

require("feed").setup({
   feeds = {
      -- These two styles both work
      "https://neovim.io/news.xml",
      {
         "https://neovim.io/news.xml",
         name = "Neovim News",
         tags = { "tech", "news" }, -- tags given are inherited by all its entries
      },

      -- three link formats:
      "https://neovim.io/news.xml", -- Regular links
      "rsshub://rsshub://apnews/topics/apf-topnews" -- RSSHub links
      "neovim/neovim/releases" -- GitHub links
   },
})

From OPML

Use Feed load_opml to import your OPML file

Use Feed export_opml to export your OPML file to load in other readers

Must start with http or https

RSSHub links are first class citizens, format is rsshub://{route}

rsshub://{route} will be resolved when fetching according to your config

Discover available {route} in RSSHub documentation rsshub://apnews/topics/apf-topnews will be resolved to https://rsshub.app/apnews/topics/apf-topnews by default

Config example:

require("feed").setup({
   rsshub = {
      instance = "127.0.0.1:1200", -- or any public instance listed here https://rsshub.netlify.app/instances
      export = "https://rsshub.app", -- used in export_opml
   },
})

GitHub user/repo links are also first class citizens,format is [github://]{user/repo}[{/releases|/commits}], so following four all work:

For now it defaults to subscribing to the commits

So first two is resolved into https://github.com/neo451/feed.nvim/commits.atom

Latter two is resolved into https://github.com/neo451/feed.nvim/releases.atom

Regex

Tags

Date

Limit

Examples

Only Shows 10 entries with tags blog and unread, without tag star, and are published within 6 month, making sure they have zig but not rust in the title.

Only show unread entries of the last six months. This is the default filter.

Only show entries about Linux or Linus from the last year.

Only show the most recent 10 previously-read entries tagged as youtube.

Only show unread entries not having vim or nvim in the title or link.

Only show entries tagged as emacs from a specific feed.

Grep

Use Feed grep to live grep all entries in your database, requires rg and one of the search backends:

Recipes

Change the highlight of the tags section and use emojis and mini.icons for tags
require("feed").setup({
   ui = {
      tags = {
         color = "String",
         format = function(id, db)
            local icons = {
               news = "📰",
               tech = "💻",
               movies = "🎬",
               games = "🎮",
               music = "🎵",
               podcast = "🎧",
               books = "📚",
               unread = "🆕",
               read = "✅",
               junk = "🚮",
               star = "⭐",
            }

            local get_icon = function(name)
               if icons[name] then
                  return icons[name]
               end
               local has_mini, MiniIcons = pcall(require, "mini.icons")
               if has_mini then
                  local icon = MiniIcons.get("filetype", name)
                  if icon then
                     return icon .. " "
                  end
               end
               return name
            end

            local tags = vim.tbl_map(get_icon, db:get_tags(id))
            table.sort(tags)
            return "[" .. table.concat(tags, ", ") .. "]"
         end,
      },
   },
})
Custom function & keymap for podcast and w3m
local function play_podcast()
   local link = require("feed").get_entry().link
   if link:find("mp3") then
      vim.ui.open(link)
   -- any other player like:
   -- vim.system({ "vlc.exe", link })
   else
      vim.notify("not a podcast episode")
   end
end

local function show_in_w3m()
   if not vim.fn.executable("w3m") then
      vim.notify("w3m not installed")
      return
   end
   local link = require("feed").get_entry().link
   local w3m = require("feed.ui.window").new({
      relative = "editor",
      col = math.floor(vim.o.columns * 0.1),
      row = math.floor(vim.o.lines * 0.1),
      width = math.floor(vim.o.columns * 0.8),
      height = math.floor(vim.o.lines * 0.8),
      border = "rounded",
      style = "minimal",
      title = "Feed w3m",
      zindex = 10,
   })
   vim.keymap.set({ "n", "t" }, "q", "<cmd>q<cr>", { silent = true, buffer = w3m.buf })
   vim.fn.jobstart({ "w3m", link }, { term = true })
   vim.cmd("startinsert")
end

require("feed").setup({
   keys = {
      index = {
         [play_podcast] = "p",
         [show_in_w3m] = "w",
      },
   },
})
Custom colorscheme only set when viewing feeds
local og_color

vim.api.nvim_create_autocmd("User", {
   pattern = "FeedShowIndex",
   callback = function()
      if not og_color then
         og_color = vim.g.colors_name
      end
      vim.cmd.colorscheme("kanagawa-lotus")
   end,
})

vim.api.nvim_create_autocmd("User", {
   pattern = "FeedQuitIndex",
   callback = function()
      vim.cmd.colorscheme(og_color)
   end,
})

Lua API

:TODO: