diff options
-rw-r--r-- | lua/inbox/config.lua | 38 | ||||
-rw-r--r-- | lua/inbox/indexers/notmuch.lua | 56 | ||||
-rw-r--r-- | lua/inbox/init.lua | 6 | ||||
-rw-r--r-- | lua/inbox/types.lua (renamed from lua/inbox/email.lua) | 36 | ||||
-rw-r--r-- | lua/inbox/utils.lua | 6 | ||||
-rw-r--r-- | lua/inbox/view.lua | 40 |
6 files changed, 111 insertions, 71 deletions
diff --git a/lua/inbox/config.lua b/lua/inbox/config.lua index 1ba2566..db122f8 100644 --- a/lua/inbox/config.lua +++ b/lua/inbox/config.lua @@ -2,6 +2,8 @@ ---@field indexer_config inbox.Indexer.Config|nil ---@field buf_options table|nil ---@field win_options table|nil +---@field columns integer[] +---@field signs table<string, table> ---@type inbox.Config local default_config = { @@ -15,21 +17,49 @@ local default_config = { }, win_options = { wrap = false, - signcolumn = "yes:3", -- can signs be used for flags?? - number = false, - relativenumber = false, + signcolumn = "auto", cursorcolumn = false, + colorcolumn = false, foldcolumn = "0", spell = false, list = false, }, + columns = { + 15, + 30, + }, + signs = { + attachment = { + text = "A", + texthl = "Constant", + }, + draft = { + text = "D", + }, + flagged = { + text = "F", + texthl = "Search", + }, + passed = { + text = "P", + }, + replied = { + text = "R", + texthl = "Directory", + }, + unread = { + text = "S", + texthl = "Special", + linehl = "Special", + }, + }, } ---@class inbox.Config local M = {} ---@param opts inbox.Config -M.setup = function(opts) +function M.setup(opts) local config = vim.tbl_deep_extend("keep", opts or {}, default_config) for k, v in pairs(config) do diff --git a/lua/inbox/indexers/notmuch.lua b/lua/inbox/indexers/notmuch.lua index 171fabf..c13e898 100644 --- a/lua/inbox/indexers/notmuch.lua +++ b/lua/inbox/indexers/notmuch.lua @@ -4,6 +4,7 @@ local Path = require("plenary.path") ---@class inbox.Indexer.Notmuch.Config local default_config = { database_dir = Path:new(vim.env.XDG_DATA_HOME, "mail").filename, + map_tag_signs = {}, } ---@class inbox.Indexer.Notmuch: inbox.Indexer, inbox.Indexer.Notmuch.Config @@ -24,12 +25,27 @@ function M.index(callback, filters) json = json .. stdout end), on_exit = vim.schedule_wrap(function(_, _, _) - if json == "" then - json = "[]" + local entries = {} + + if json and json ~= "" then + entries = vim.json.decode(json) or {} + end + + local rows = {} + local signs = {} + + for lnum, entry in ipairs(entries) do + local cols = M.summarize(entry) + + for _, tag in ipairs(entry.tags) do + local sign = M.map_tag_signs[tag] or tag + table.insert(signs, { sign, lnum }) + end + + table.insert(rows, cols) end - local entries = vim.json.decode(json) - callback(entries) + callback(rows, signs) end), }) @@ -38,16 +54,42 @@ function M.index(callback, filters) for name, value in pairs(filters) do table.insert(filter_args, ("%s:%s"):format(name, value)) end + local filter_args_str = table.concat(filter_args, " and ") vim.list_extend(job.args, vim.split(filter_args_str, " ")) - vim.print(job.args) - job:start() end +---@param summary inbox.Summary +---@return table sanitized sanitized summary +function M.summarize(summary) + local date = summary.date_relative + + local from + if type(summary.authors) == "table" then + from = summary.authors[1] --[[@as string]] + else + from = summary.authors --[[@as string]] + end + + local subject + if type(summary.subject) == "table" then + subject = summary.subject[1] --[[@as string]] + else + subject = summary.subject --[[@as string]] + end + subject = subject:gsub("\r?\n", " ") + + return { + date, + from, + subject, + } +end + ---@param opts inbox.Indexer.Notmuch.Config -M.setup = function(opts) +function M.setup(opts) local config = vim.tbl_deep_extend("keep", opts or {}, default_config) for k, v in pairs(config) do diff --git a/lua/inbox/init.lua b/lua/inbox/init.lua index 5841481..b00ed84 100644 --- a/lua/inbox/init.lua +++ b/lua/inbox/init.lua @@ -15,9 +15,15 @@ end function M.setup(opts) local config = require("inbox.config") local indexers = require("inbox.indexers") + local utils = require("inbox.utils") config.setup(opts) indexers.setup(config.indexer_config) + + for sign, value in pairs(config.signs) do + local name = utils.sign_name(sign) + vim.fn.sign_define(name, value) + end end return M diff --git a/lua/inbox/email.lua b/lua/inbox/types.lua index c680b16..1d2c549 100644 --- a/lua/inbox/email.lua +++ b/lua/inbox/types.lua @@ -42,39 +42,3 @@ ---| "text/plain" ---| "text/html" ---| string - -local M = {} - -M.summary_widths = { - 10, - 30, -} - ----@param summary inbox.Summary ----@return table sanitized sanitized summary -function M.sanitize_summary(summary) - local date = summary.date_relative:gsub("^([A-Z][a-z][a-z])%w%w+", "%1.") - - local from - if type(summary.authors) == "table" then - from = summary.authors[1] --[[@as string]] - else - from = summary.authors --[[@as string]] - end - - local subject - if type(summary.subject) == "table" then - subject = summary.subject[1] --[[@as string]] - else - subject = summary.subject --[[@as string]] - end - subject = subject:gsub("\r?\n", " ") - - return { - date, - from, - subject, - } -end - -return M diff --git a/lua/inbox/utils.lua b/lua/inbox/utils.lua index 93b4d47..ddc809d 100644 --- a/lua/inbox/utils.lua +++ b/lua/inbox/utils.lua @@ -77,4 +77,10 @@ function M.render_winbar(winid, cols, col_widths) vim.api.nvim_set_option_value("winbar", string.rep(" ", offset) .. winbar, { scope = "local", win = winid }) end +---@param name string +---@return string sign_name +function M.sign_name(name) + return "Inbox" .. name:gsub("^%l", string.upper) +end + return M diff --git a/lua/inbox/view.lua b/lua/inbox/view.lua index cfe256c..252bef3 100644 --- a/lua/inbox/view.lua +++ b/lua/inbox/view.lua @@ -1,5 +1,4 @@ local config = require("inbox.config") -local email = require("inbox.email") local indexers = require("inbox.indexers") local utils = require("inbox.utils") @@ -44,45 +43,38 @@ function M.render_buffer(bufnr) return false end - local function render_buffer_async_callback(entries) + local function render_buffer_async_callback(entries, signs) -- TODO: sort entries? - utils.render_table({ {} }, email.summary_widths) - - local summaries = {} - - -- local signs - for _, entry in ipairs(entries) do - local cols = email.sanitize_summary(entry) - - -- TODO: format signs - -- local _ = email.tags - -- table.insert(signs, email.tags) - - table.insert(summaries, cols) - end - - -- TODO: configurable table columns and column widths - - local lines, _ = utils.render_table(summaries, email.summary_widths) + local lines, _ = utils.render_table(entries, config.columns) -- TODO: setup highlights - -- TODO: setup signs (tags) vim.bo[bufnr].modifiable = true vim.api.nvim_buf_set_lines(bufnr, 0, -1, true, lines) vim.bo[bufnr].modifiable = false vim.bo[bufnr].modified = false + for _, sign_lnum in pairs(signs) do + local sign, lnum = unpack(sign_lnum) + local name = utils.sign_name(sign) + + if #vim.fn.sign_getdefined(name) > 0 then + vim.fn.sign_place(0, "inbox", name, bufnr, { lnum = lnum }) + end + end + local winid = vim.api.nvim_get_current_win() for k, v in pairs(config.win_options) do vim.api.nvim_set_option_value(k, v, { scope = "local", win = winid }) end - local winbar = utils.render_row({ "Date", "From", "Subject" }, email.summary_widths) - local offset = vim.fn.getwininfo(winid)[1].textoff + 1 - vim.api.nvim_set_option_value("winbar", string.rep(" ", offset) .. winbar, { scope = "local", win = winid }) + local offset = vim.fn.getwininfo(winid)[1].textoff + local winbar_col = config.columns + table.insert(winbar_col, 1, offset) + local winbar = utils.render_row({ "Flags", "Date", "From", "Subject" }, winbar_col) + vim.api.nvim_set_option_value("winbar", winbar, { scope = "local", win = winid }) end -- TODO: cache entries |