summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorToby Vincent <tobyv@tobyvin.dev>2023-10-16 18:14:48 -0500
committerToby Vincent <tobyv@tobyvin.dev>2023-10-16 18:14:48 -0500
commita3e2977d898e60e34aaf8f681ef8a5413eaa55fd (patch)
tree5d8c9e741bb9e2600628e1436c06bdd721d85750
parent0de045c6a942f90c0e5c966c24855172d683ddfa (diff)
feat: add signs for tags
-rw-r--r--lua/inbox/config.lua38
-rw-r--r--lua/inbox/indexers/notmuch.lua56
-rw-r--r--lua/inbox/init.lua6
-rw-r--r--lua/inbox/types.lua (renamed from lua/inbox/email.lua)36
-rw-r--r--lua/inbox/utils.lua6
-rw-r--r--lua/inbox/view.lua40
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