diff options
author | Toby Vincent <tobyv@tobyvin.dev> | 2023-10-21 21:46:07 -0500 |
---|---|---|
committer | Toby Vincent <tobyv@tobyvin.dev> | 2023-10-21 21:46:07 -0500 |
commit | cc69cfc85ce5abd4975c020b89015dc58e056208 (patch) | |
tree | 18fb22a6769f29948dd4bfa1eefbab5f2d26f6c0 /lua/inbox | |
parent | 29cb0cd012bb377178fe8fa7426456b1cc8ab55f (diff) |
feat: add predefined filters
Diffstat (limited to 'lua/inbox')
-rw-r--r-- | lua/inbox/config.lua | 29 | ||||
-rw-r--r-- | lua/inbox/filters/w3m.lua | 21 | ||||
-rw-r--r-- | lua/inbox/indexers/notmuch.lua | 41 | ||||
-rw-r--r-- | lua/inbox/types.lua | 3 | ||||
-rw-r--r-- | lua/inbox/view.lua | 103 |
5 files changed, 112 insertions, 85 deletions
diff --git a/lua/inbox/config.lua b/lua/inbox/config.lua index 4692f5c..634b35d 100644 --- a/lua/inbox/config.lua +++ b/lua/inbox/config.lua @@ -54,12 +54,39 @@ local default_config = { ---@class inbox.Config local M = {} +function M.try_resolve(value, module) + if type(value) == "string" then + local is_ok, result = pcall(require, ("inbox.%s.%s"):format(module, value)) + if is_ok then + value = result + end + end + return value +end + +function M.parse_filters(filter_config) + local filters = {} + for content_type, items in pairs(filter_config) do + filters[content_type] = {} + for _, value in pairs(items) do + table.insert(filters[content_type], M.try_resolve(value, "filters")) + end + end + return filters +end + ---@param opts inbox.Config function M.setup(opts) local config = vim.tbl_deep_extend("keep", opts or {}, default_config) for k, v in pairs(config) do - M[k] = v + if k == "filters" then + M[k] = M.parse_filters(v) + elseif k == "indexer" then + M[k] = M.try_resolve(v, k) + else + M[k] = v + end end end diff --git a/lua/inbox/filters/w3m.lua b/lua/inbox/filters/w3m.lua new file mode 100644 index 0000000..e64781f --- /dev/null +++ b/lua/inbox/filters/w3m.lua @@ -0,0 +1,21 @@ +local M = { + command = "socksify", + args = function(bufnr) + return { + "w3m", + "-I", + "UTF-8", + "-T", + "text/html", + "-cols", + vim.bo[bufnr].textwidth, + "-dump", + "-o", + "display_image=false", + "-o", + "display_link_number=true", + } + end, +} + +return M diff --git a/lua/inbox/indexers/notmuch.lua b/lua/inbox/indexers/notmuch.lua index 83f9ac9..a05c112 100644 --- a/lua/inbox/indexers/notmuch.lua +++ b/lua/inbox/indexers/notmuch.lua @@ -188,47 +188,6 @@ function M.flatten_parts(part, parts) return parts end -function M.get_part(id, content_type, callback) - local entry = M.cache(id) - - if entry == nil then - utils.error("Failed to get entry", { id = id }) - return - end - - ---@type inbox.EntryPart? - local part - - for _, p in pairs(entry.parts) do - if content_type == nil or p["content-type"] == content_type then - part = p - break - end - end - - vim.print(part) - - if part == nil then - utils.error("Failed to find message part for entry", { id = id, ["content-type"] = content_type }) - return - end - - local job = Job:new({ - command = "notmuch", - args = { "show", ("--part=%s"):format(part.id), ("id:%s"):format(entry.id) }, - 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 - ---@param opts inbox.Indexer.Notmuch.Config function M.setup(opts) local config = vim.tbl_deep_extend("keep", opts or {}, default_config) diff --git a/lua/inbox/types.lua b/lua/inbox/types.lua index 691f6cf..a4105b0 100644 --- a/lua/inbox/types.lua +++ b/lua/inbox/types.lua @@ -3,7 +3,7 @@ ---@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 filters table<inbox.ContentType, inbox.PartFilter[]> ---@field columns integer[] ---@field flags table<string, table> ---@field headers inbox.HeaderKey[] @@ -30,7 +30,6 @@ ---@field index? fun(maildir: string, cb: fun(ids: string[], entries: inbox.Summary[], signs: (string | integer)[][]), opts?: table) ---@field get_entry? fun(id: string): inbox.Entry|nil ---@field get_parts? fun(id: string): inbox.ContentType[] ----@field get_part? fun(id: string, content_type: inbox.ContentType, callback: fun(entry: inbox.Entry, part_index: integer, part_lines: string[])) ---@alias inbox.Indexer.Config ---| "notmuch" diff --git a/lua/inbox/view.lua b/lua/inbox/view.lua index 5c40d5f..3ba20c6 100644 --- a/lua/inbox/view.lua +++ b/lua/inbox/view.lua @@ -34,20 +34,22 @@ function M.render_buffer(bufnr) end ---@param bufnr integer ----@param lines string[] ----@param start integer? ----@param end_ integer? -function M.set_buffer_content(bufnr, lines, start, end_) - if start == nil then - start = 0 - end - - if end_ == nil then - end_ = -1 +---@param start integer +---@param end_ integer +---@param strict_indexing boolean +---@param lines string[]? +---@param escape_ascii boolean? +function M.buf_set_lines(bufnr, start, end_, strict_indexing, lines, escape_ascii) + local buf_writer + if escape_ascii and pcall(require, "baleia") then + local baleia = require("baleia").setup() + buf_writer = baleia.buf_set_lines + else + buf_writer = vim.api.nvim_buf_set_lines end vim.bo[bufnr].modifiable = true - vim.api.nvim_buf_set_lines(bufnr, start, end_, true, lines) + buf_writer(bufnr, start, end_, strict_indexing, lines or {}) vim.bo[bufnr].modifiable = false vim.bo[bufnr].modified = false end @@ -84,7 +86,7 @@ function M.render_inbox(bufnr, maildir) vim.api.nvim_set_option_value(k, v, { scope = "local", win = winid }) end - M.set_buffer_content(bufnr, lines) + M.buf_set_lines(bufnr, 0, -1, true, lines) utils.set_highlights(bufnr, highlights) utils.set_signs(bufnr, signs) @@ -141,6 +143,25 @@ function M.initialize_entry(maildir, id, content_type) M.render_headers(bufnr, id) M.render_entry(bufnr, id, content_type) + vim.api.nvim_create_autocmd({ "BufModifiedSet", "BufWinEnter" }, { + group = "Inbox", + buffer = bufnr, + callback = function() + for _, winid in pairs(vim.fn.win_findbuf(bufnr)) do + local winbar = string.format( + "%sPart: %s", + string.rep(" ", vim.fn.getwininfo(winid)[1].textoff), + vim.b[bufnr].inbox_content_type + ) + + vim.api.nvim_set_option_value("winbar", winbar, { + scope = "local", + win = winid, + }) + end + end, + }) + return bufnr end @@ -172,13 +193,10 @@ function M.render_headers(bufnr, id) local cursor_pos = vim.fn.getpos(".") - if vim.b[bufnr].header_count ~= nil then - M.set_buffer_content(bufnr, {}, 0, vim.b[bufnr].header_count) - end - - M.set_buffer_content(bufnr, lines, 0, 0) + M.buf_set_lines(bufnr, 0, vim.b[bufnr].header_lines or 0, true, {}) + M.buf_set_lines(bufnr, 0, 0, true, lines) - vim.b[bufnr].header_count = #lines + vim.b[bufnr].header_lines = #lines vim.fn.setpos(".", cursor_pos) end @@ -209,34 +227,37 @@ function M.render_entry(bufnr, id, 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) + M.buf_set_lines(bufnr, vim.b[bufnr].header_lines or 0, -1, true, lines) 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, - }) + for i, filter in pairs(config.filters[content_type] or {}) do + for key, value in pairs(filter) do + if type(value) == "function" then + filter[key] = value(bufnr) + else + filter[key] = value + end + end + + local opts = { + command = filter.command, + args = filter.args, + } + + if job == nil then + opts.writer = part.content 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), - }) + opts.writer = job end + + if i == #config.filters[content_type] then + opts.on_exit = vim.schedule_wrap(function(self) + M.buf_set_lines(bufnr, vim.b[bufnr].header_lines or 0, -1, true, self:result(), true) + end) + end + + job = Job:new(opts) end job:start() |