Skip to content

Commit

Permalink
fix(db): proper AND/OR logic for multiple regex
Browse files Browse the repository at this point in the history
  • Loading branch information
neo451 committed Feb 20, 2025
1 parent 9f4c8b6 commit 6e92a96
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 180 deletions.
66 changes: 41 additions & 25 deletions lua/feed/db/local.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,25 @@ local ut = require("feed.utils")
local uv = vim.uv

---@class feed.db
---@field dir string
---@field dir feed.path
---@field feeds feed.opml
---@field index table
---@field tags table<string, table<string, boolean>>
---@field add fun(db: feed.db, entry: feed.entry, tags: string[]?)
---@field rm fun(db: feed.db, id: string)
---@field iter fun(db: feed.db, sort: boolean?): Iter
---@field filter fun(db: feed.db, query: string) : string[]
---@field save_entry fun(db: feed.db, id: string): boolean
---@field save_feeds fun(db: feed.db): boolean
---@field save_feeds fun(db: feed.db)
---@field save_index fun(db: feed.db)
---@field save_tags fun(db: feed.db)
---@field tag fun(db: feed.db, id: string, tag: string | string[])
---@field untag fun(db: feed.db, id: string, tag: string | string[])
---@field blowup fun(db: feed.db)
---@field update fun(db: feed.db)
---@field lastUpdated fun(db: feed.db)
---@field lastUpdated fun(db: feed.db): string
local M = {}

---@param fp string
---@param fp feed.path
---@param t any
local ensure_exists = function(fp, t)
if not uv.fs_stat(tostring(fp)) then
Expand Down Expand Up @@ -101,6 +102,19 @@ function M:__index(k)
return r
end

---@param id string
---@param entry feed.entry
function M:__newindex(id, entry)
if not id or if_path(id, self.dir) then
return
end
mem[id] = entry
local time = entry.time
table.insert(self.index, { id, time })
Path.append(self.dir / "index", time .. " " .. id .. "\n")
Path.save(self.dir / "object" / id, entry)
end

function M:update()
local feeds = Path.load(self.dir / "feeds.lua")
rawset(self, "feeds", feeds)
Expand All @@ -120,25 +134,11 @@ function M:lastUpdated()
return os.date("%c", vim.fn.getftime(tostring(self.dir / "feeds.lua")))
end

---@param id string
---@param entry feed.entry
function M:__newindex(id, entry)
if not id or if_path(id, self.dir) then
return
end
mem[id] = entry
local time = entry.time
table.insert(self.index, { id, time })
Path.append(self.dir / "index", time .. " " .. id .. "\n")
Path.save(self.dir / "object" / id, entry)
end

---@param id string | string[]
---@param tag string
function M:tag(id, tag)
local function tag_one(t)
self.tags[t][id] = true
self:save_tags()
end
if type(tag) == "string" then
if tag:find(",") then
Expand All @@ -153,28 +153,29 @@ function M:tag(id, tag)
tag_one(v)
end
end
self:save_tags()
end

---@param id string | string[]
---@param tag string
function M:untag(id, tag)
local function tag_one(t)
local function untag_one(t)
self.tags[t][id] = nil
self:save_tags()
end
if type(tag) == "string" then
if tag:find(",") then
for t in ut.split(tag, ",") do
tag_one(t)
untag_one(t)
end
else
tag_one(tag)
untag_one(tag)
end
elseif type(tag) == "table" then
for _, v in ipairs(tag) do
tag_one(v)
untag_one(v)
end
end
self:save_tags()
end

function M:sort()
Expand Down Expand Up @@ -285,7 +286,22 @@ function M:filter(str)
return false
end
for _, reg in ipairs(q.re) do
if not reg:match_str(entry.title) or not reg:match_str(entry.link) then
if reg:match_str(entry.title) or reg:match_str(entry.link) then
return true
end
end
return false
end)
end

if q.not_re then
iter = iter:filter(function(id)
local entry = self[id]
if not entry or not entry.title then
return false
end
for _, reg in ipairs(q.not_re) do
if reg:match_str(entry.title) or reg:match_str(entry.link) then
return false
end
end
Expand Down
3 changes: 1 addition & 2 deletions lua/feed/db/path.lua
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,8 @@ Path.new = function(path)
})
end

---@param dir
---@param dir string
local function rmdir(dir)
dir = type(dir) == "table" and tostring(dir) or dir
for name, t in vim.fs.dir(dir) do
name = dir .. "/" .. name
local ok = (t == "directory") and uv.fs_rmdir(name) or uv.fs_unlink(name)
Expand Down
20 changes: 8 additions & 12 deletions lua/feed/db/query.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,21 @@ local M = {}
---@class feed.query
---@field after? integer #@
---@field before? integer #@
---@field limit? integer ##
---@field must_have? string[] #+
---@field must_not_have? string[] #-
---@field feed? vim.regex #=
---@field not_feed? vim.regex #~
---@field limit? number ##
---@field re? vim.regex[]
---@field not_re? vim.regex[] ##

---wrapper arround vim.regex, ! is inverse, respects vim.o.ignorecase
---@param str string
local function build_regex(str)
local pattern
if str:sub(0, 1) == "!" then
pattern = [[^\(.*]] .. vim.fn.escape(str:sub(2), "\\") .. [[.*\)\@!.*]]
-- pattern = [[^\(.*]] .. vim.fn.escape(str:sub(2), "\\") .. [[.*\)\@!.*]]
pattern = str:sub(2)
else
pattern = str
end
Expand All @@ -35,34 +37,28 @@ M._build_regex = build_regex
---@return feed.query
function M.parse_query(str)
str = str:gsub("+unread", "-read"):gsub("-unread", "+read")
local query = {}
local query = vim.defaulttable()
for q in vim.gsplit(str, " ") do
local kind = q:sub(1, 1)
if kind == "@" then
query.after, query.before = date.parse_filter(q)
elseif kind == "#" then
query.limit = tonumber(q:sub(2))
elseif kind == "+" then
if not query.must_have then
query.must_have = {}
end
table.insert(query.must_have, q:sub(2))
elseif kind == "-" then
if not query.must_not_have then
query.must_not_have = {}
end
table.insert(query.must_not_have, q:sub(2))
elseif kind == "=" then
query.feed = build_regex(q:sub(2))
elseif kind == "~" then
query.not_feed = build_regex(q:sub(2))
elseif kind == "!" then
table.insert(query.not_re, build_regex(q))
else
if not query.re then
query.re = {}
end
table.insert(query.re, build_regex(q))
end
end
setmetatable(query, nil)
return query
end

Expand Down
6 changes: 3 additions & 3 deletions lua/feed/ui.lua
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ local function image_attach(buf)
return
end
pcall(function()
local ok, f = Snacks.image.doc.inline(buf)
local ok, f = pcall(Snacks.image.doc.inline, buf)
return ok and f and f()
end)
end
Expand Down Expand Up @@ -251,8 +251,6 @@ local function show_entry(ctx)
BufLeave = function(self)
vim.o.cmdheight = og.cmdheight
set_colorscheme(og.colorscheme)
self:close()
state.entry = nil
end,
},
})
Expand Down Expand Up @@ -290,8 +288,10 @@ end
M.quit = function()
if ut.in_index() then
state.index:close()
state.index = nil
elseif ut.in_entry() then
state.entry:close()
state.entry = nil
end
end

Expand Down
Loading

0 comments on commit 6e92a96

Please sign in to comment.