summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorToby Vincent <tobyv@tobyvin.dev>2023-10-20 19:20:40 -0500
committerToby Vincent <tobyv@tobyvin.dev>2023-10-20 19:21:20 -0500
commit29cb0cd012bb377178fe8fa7426456b1cc8ab55f (patch)
treee57e06d81d2f84ebd96a74dda9e955d0061d721f
parentddb7133e0df362edf6d0de7b79d56a2473637a97 (diff)
feat: impl message-part pre-processors
-rw-r--r--lua/inbox/indexers/notmuch.lua55
-rw-r--r--lua/inbox/init.lua5
-rw-r--r--lua/inbox/types.lua6
-rw-r--r--lua/inbox/utils.lua29
-rw-r--r--lua/inbox/view.lua73
5 files changed, 122 insertions, 46 deletions
diff --git a/lua/inbox/indexers/notmuch.lua b/lua/inbox/indexers/notmuch.lua
index 5e998eb..83f9ac9 100644
--- a/lua/inbox/indexers/notmuch.lua
+++ b/lua/inbox/indexers/notmuch.lua
@@ -57,16 +57,12 @@ end
function M.index(maildir, callback, opts)
opts = opts or {}
- local sbuf = {}
local job = Job:new({
command = "notmuch",
args = { "search", "--format=json" },
- on_stdout = vim.schedule_wrap(function(_, stdout)
- table.insert(sbuf, stdout)
- end),
- on_exit = vim.schedule_wrap(function()
+ on_exit = vim.schedule_wrap(function(j)
---@type inbox.Notmuch.SearchResult[]
- local results = utils.json_decode(table.concat(sbuf, "\n"))
+ local results = utils.json_decode(table.concat(j:result(), "\n"))
---@type inbox.Summary[]
local entries = {}
@@ -151,7 +147,7 @@ function M.show_id(id)
local job = Job:new({
command = "notmuch",
- args = { "show", "--format=json", ("id:%s"):format(id) },
+ args = { "show", "--format=json", "--include-html", ("id:%s"):format(id) },
})
local stdout = job:sync()
@@ -162,10 +158,10 @@ function M.show_id(id)
end
entry.tags = M.parse_tags(entry.tags)
- entry.parts = M.flatten_parts(entry.body[1])
- table.sort(entry.parts, function(a, b)
- return a.id < b.id
- end)
+ entry.parts = {}
+ for _, part in pairs(M.flatten_parts(entry.body[1])) do
+ entry.parts[part["content-type"]] = part
+ end
return entry
end
@@ -196,45 +192,40 @@ function M.get_part(id, content_type, callback)
local entry = M.cache(id)
if entry == nil then
- vim.notify(("Failed to get entry with id: %s"):format(id), vim.log.levels.ERROR)
+ utils.error("Failed to get entry", { id = id })
return
end
- local parts = entry.parts
+ ---@type inbox.EntryPart?
+ local part
- local index = 1
- if content_type ~= nil then
- for i, p in pairs(entry.parts) do
- if p["content-type"] == content_type then
- index = i
- break
- end
+ for _, p in pairs(entry.parts) do
+ if content_type == nil or p["content-type"] == content_type then
+ part = p
+ break
end
- else
- index = 1
end
- local part = parts[index]
-
- ---@type inbox.EntryPart?
+ vim.print(part)
if part == nil then
- vim.notify(("Failed to find message part for entry id: %s"):format(id), vim.log.levels.ERROR)
+ utils.error("Failed to find message part for entry", { id = id, ["content-type"] = content_type })
return
end
- local sbuf = {}
local job = Job:new({
command = "notmuch",
args = { "show", ("--part=%s"):format(part.id), ("id:%s"):format(entry.id) },
- on_stdout = vim.schedule_wrap(function(_, stdout)
- table.insert(sbuf, stdout)
- end),
- on_exit = vim.schedule_wrap(function()
- callback(entry, index, sbuf)
+ on_exit = vim.schedule_wrap(function(j)
+ callback(entry, j:result())
end),
})
+ -- if part["content-type"] == "text/html" then
+ -- job = Job:new({ command = "/usr/lib/aerc/filters/wrap", writer = job })
+ -- job = Job:new({ command = "/usr/lib/aerc/filters/colorize", writer = job })
+ -- end
+
job:start()
end
diff --git a/lua/inbox/init.lua b/lua/inbox/init.lua
index f3869c0..582a3a0 100644
--- a/lua/inbox/init.lua
+++ b/lua/inbox/init.lua
@@ -30,6 +30,11 @@ function M.select()
end
function M.open(maildir)
+ local config = require("inbox.config")
+ if maildir == nil then
+ maildir = config.default_maildir
+ end
+
local view = require("inbox.view")
if M.buffers[maildir] == nil or vim.api.nvim_buf_is_valid(M.buffers[maildir]) then
diff --git a/lua/inbox/types.lua b/lua/inbox/types.lua
index 4a3d320..691f6cf 100644
--- a/lua/inbox/types.lua
+++ b/lua/inbox/types.lua
@@ -1,11 +1,17 @@
---@class inbox.Config
+---@field default_maildir string|nil
---@field indexer_config inbox.Indexer.Config|nil
---@field buf_options table|nil
---@field win_options table|nil
+---@field filters table<inbox.ContentType, inbox.PartFilter>
---@field columns integer[]
---@field flags table<string, table>
---@field headers inbox.HeaderKey[]
+---@class inbox.PartFilter
+---@field command string
+---@field args string[]
+
---@alias inbox.HeaderKey
---| "Subject"
---| "Date"
diff --git a/lua/inbox/utils.lua b/lua/inbox/utils.lua
index c5954a8..8d82b7d 100644
--- a/lua/inbox/utils.lua
+++ b/lua/inbox/utils.lua
@@ -4,6 +4,35 @@ local M = {}
---@field [1] string text
---@field [2] string hl
+---@param msg string
+---@param vars table<string, string>
+---@param level integer|nil
+function M.notify(msg, vars, level)
+ for name, value in pairs(vars) do
+ string.format("%s\n%s: %s", msg, name, value)
+ end
+
+ vim.notify(msg, level, { title = "inbox.nvim" })
+end
+
+---@param msg string
+---@param vars table<string, string>
+function M.info(msg, vars)
+ M.notify(msg, vars, vim.log.levels.INFO)
+end
+
+---@param msg string
+---@param vars table<string, string>
+function M.warn(msg, vars)
+ M.notify(msg, vars, vim.log.levels.WARN)
+end
+
+---@param msg string
+---@param vars table<string, string>
+function M.error(msg, vars)
+ M.notify(msg, vars, vim.log.levels.ERROR)
+end
+
---@param text string
---@param length nil|integer
---@return string
diff --git a/lua/inbox/view.lua b/lua/inbox/view.lua
index a79bf17..5c40d5f 100644
--- a/lua/inbox/view.lua
+++ b/lua/inbox/view.lua
@@ -126,11 +126,13 @@ function M.initialize_entry(maildir, id, content_type)
vim.keymap.set("n", "<C-h>", require("inbox").toggle_headers, { buffer = bufnr })
vim.keymap.set("n", "<C-n>", function()
- local k, v = next(vim.b[bufnr].inbox_parts, vim.b[bufnr].inbox_part_index)
- if k == nil then
- k, v = next(vim.b[bufnr].inbox_parts)
+ local k
+ if vim.b[bufnr].inbox_content_type then
+ k = next(vim.b[bufnr].inbox_parts, vim.b[bufnr].inbox_content_type)
+ else
+ k = next(vim.b[bufnr].inbox_parts)
end
- M.render_entry(bufnr, id, v["content-type"])
+ M.render_entry(bufnr, id, k)
end, { buffer = bufnr })
vim.b[bufnr].inbox_id = id
@@ -182,20 +184,63 @@ function M.render_headers(bufnr, id)
end
function M.render_entry(bufnr, id, content_type)
+ local Job = require("plenary.job")
local indexer = indexers.get_indexer()
+ local entry = indexer.get_entry(id)
+
+ if entry == nil then
+ utils.error("Failed to get entry", { id = id })
+ return
+ end
+
+ if content_type == nil then
+ content_type = next(entry.parts)
+ end
+
+ local part = entry.parts[content_type]
+
+ if part == nil then
+ utils.error("Failed to find message part for entry", { id = id, ["content-type"] = content_type })
+ return
+ end
- indexer.get_part(id, content_type, function(entry, index, lines)
+ vim.b[bufnr].inbox_parts = entry.parts
+ vim.b[bufnr].inbox_content_type = content_type
+
+ if vim.tbl_isempty(config.filters[content_type] or {}) then
+ local lines = vim.split(part.content, "\n")
M.set_buffer_content(bufnr, lines, vim.b[bufnr].header_count)
- vim.b[bufnr].inbox_parts = entry.parts
- vim.b[bufnr].inbox_part_index = index
+ else
+ local job
+
+ for i, filter in pairs(config.filters[content_type]) do
+ if i == 1 then
+ job = Job:new({
+ command = filter.command,
+ args = filter.args,
+ writer = part.content,
+ })
+ elseif i < #config.filters[content_type] then
+ job = Job:new({
+ command = filter.command,
+ args = filter.args,
+ writer = job,
+ })
+ else
+ job = Job:new({
+ command = filter.command,
+ args = filter.args,
+ writer = job,
+ on_exit = vim.schedule_wrap(function(self)
+ vim.print(self)
+ M.set_buffer_content(bufnr, self:result(), vim.b[bufnr].header_count)
+ end),
+ })
+ end
+ end
- local winid = vim.api.nvim_get_current_win()
- vim.api.nvim_set_option_value(
- "winbar",
- vim.b[bufnr].inbox_parts[vim.b[bufnr].inbox_part_index]["content-type"],
- { scope = "local", win = winid }
- )
- end)
+ job:start()
+ end
end
return M