diff options
author | Toby Vincent <tobyv@tobyvin.dev> | 2023-10-20 19:20:40 -0500 |
---|---|---|
committer | Toby Vincent <tobyv@tobyvin.dev> | 2023-10-20 19:21:20 -0500 |
commit | 29cb0cd012bb377178fe8fa7426456b1cc8ab55f (patch) | |
tree | e57e06d81d2f84ebd96a74dda9e955d0061d721f | |
parent | ddb7133e0df362edf6d0de7b79d56a2473637a97 (diff) |
feat: impl message-part pre-processors
-rw-r--r-- | lua/inbox/indexers/notmuch.lua | 55 | ||||
-rw-r--r-- | lua/inbox/init.lua | 5 | ||||
-rw-r--r-- | lua/inbox/types.lua | 6 | ||||
-rw-r--r-- | lua/inbox/utils.lua | 29 | ||||
-rw-r--r-- | lua/inbox/view.lua | 73 |
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 |