From 29f108b5c484f01fcbd7bb8234af035da6971607 Mon Sep 17 00:00:00 2001 From: Toby Vincent Date: Sun, 22 Oct 2023 13:05:32 -0500 Subject: refactor: clean up functions --- lua/inbox/config.lua | 9 ++++---- lua/inbox/indexers.lua | 33 ++++++++++++--------------- lua/inbox/indexers/notmuch.lua | 29 ++--------------------- lua/inbox/init.lua | 52 +++++++++++++++--------------------------- lua/inbox/types.lua | 26 ++++++++++----------- lua/inbox/utils.lua | 23 ++++++++++++++----- lua/inbox/view.lua | 13 ++++------- 7 files changed, 74 insertions(+), 111 deletions(-) diff --git a/lua/inbox/config.lua b/lua/inbox/config.lua index 2f7f47d..9e62353 100644 --- a/lua/inbox/config.lua +++ b/lua/inbox/config.lua @@ -1,8 +1,11 @@ -local utils = require("inbox.utils") +local Path = require("plenary.path") ---@type inbox.Config local default_config = { - indexer_config = "notmuch", + indexer = "notmuch", + indexer_config = { + database_dir = Path:new(vim.env.XDG_DATA_HOME, "mail").filename, + }, buf_options = {}, win_options = { wrap = false, @@ -84,8 +87,6 @@ function M.setup(opts) for k, v in pairs(config) do 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 diff --git a/lua/inbox/indexers.lua b/lua/inbox/indexers.lua index 0c87988..46bb2df 100644 --- a/lua/inbox/indexers.lua +++ b/lua/inbox/indexers.lua @@ -1,37 +1,34 @@ +local utils = require("inbox.utils") + local M = {} ---@return inbox.Indexer function M.get_indexer() if not M.indexer then local config = require("inbox.config") - M.setup(config.indexer_config) + M.setup(config) end return M.indexer end ----@param opts inbox.Indexer.Config +---@param opts inbox.Config function M.setup(opts) - if not opts then - vim.notify("No indexer set", vim.log.levels.ERROR) - return nil - end - - if type(opts) == "string" then - opts = { name = opts } + if opts.indexer == nil then + utils.error("No indexer provided") + return end - local ok, indexer = pcall(require, string.format("inbox.indexers.%s", opts.name)) - if not ok then - vim.notify(string.format("Indexer not found: '%s'", indexer), vim.log.levels.ERROR) - end + local is_ok, indexer = pcall(require, string.format("inbox.indexers.%s", opts.indexer)) + if not is_ok then + utils.error("Indexer not found", { indexer = opts.indexer }) + elseif not indexer.available() then + utils.error("Indexer not available", { indexer = opts.indexer }) + else + -- TODO: Validate indexer spec - -- TODO: Validate indexer spec - if indexer.available() then M.indexer = indexer - M.indexer.setup(opts) - else - vim.notify(string.format("Indexer not available: '%s'", indexer), vim.log.levels.ERROR) + M.indexer.setup(opts.indexer_config) end end diff --git a/lua/inbox/indexers/notmuch.lua b/lua/inbox/indexers/notmuch.lua index a06991a..0a6c851 100644 --- a/lua/inbox/indexers/notmuch.lua +++ b/lua/inbox/indexers/notmuch.lua @@ -5,7 +5,6 @@ local utils = require("inbox.utils") ---@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 @@ -54,9 +53,7 @@ function M.available() return vim.fn.executable("notmuch") == 1 end -function M.index(maildir, callback, opts) - opts = opts or {} - +function M.index(maildir, callback) local job = Job:new({ command = "notmuch", args = { "search", "--format=json" }, @@ -72,7 +69,7 @@ function M.index(maildir, callback, opts) for lnum, result in ipairs(results) do ids[lnum] = (result.query[1]:gsub("^id:", "")) entries[lnum] = M.summarize(result) - for _, sign in pairs(M.parse_tags(result.tags)) do + for _, sign in pairs(result.tags) do table.insert(signs, { sign, lnum }) end end @@ -84,30 +81,9 @@ function M.index(maildir, callback, opts) local folder = Path:new(maildir):make_relative(M.database_dir) table.insert(job.args, ("folder:%s"):format(folder)) - -- TODO: handle different operators i.e. "not", "or", etc. - for name, value in pairs(opts) do - table.insert(job.args, "and") - table.insert(job.args, ("%s:%s"):format(name, value)) - end - job:start() end ----@private ----@param tags string[] ----@return string[] parsed tags -function M.parse_tags(tags) - local signs = {} - for _, tag in ipairs(tags) do - if M.map_tag_signs[tag] ~= nil then - table.insert(signs, M.map_tag_signs[tag]) - else - table.insert(signs, tag) - end - end - return signs -end - ---@private ---@param item inbox.Notmuch.SearchResult ---@return inbox.Summary summary @@ -166,7 +142,6 @@ function M.show_id(id) local headers = utils.parse_headers(lines) entry.headers = headers - entry.tags = M.parse_tags(entry.tags) entry.parts = {} for _, part in pairs(M.flatten_parts(entry.body[1])) do entry.parts[part["content-type"]] = part diff --git a/lua/inbox/init.lua b/lua/inbox/init.lua index 582a3a0..bce9020 100644 --- a/lua/inbox/init.lua +++ b/lua/inbox/init.lua @@ -1,3 +1,8 @@ +local config = require("inbox.config") +local indexers = require("inbox.indexers") +local utils = require("inbox.utils") +local view = require("inbox.view") + local M = { buffers = {}, } @@ -30,13 +35,10 @@ 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 M.buffers[maildir] = view.initialize_inbox(maildir) end @@ -53,9 +55,6 @@ function M.open_entry(id, content_type) end if M.buffers[id] == nil or vim.api.nvim_buf_is_valid(M.buffers[id]) then - local utils = require("inbox.utils") - local view = require("inbox.view") - local maildir = utils.parse_scheme(0) if maildir == nil then return @@ -86,25 +85,28 @@ function M.select_part() end function M.toggle_headers(bufnr) - local view = require("inbox.view") - if bufnr == nil or bufnr == 0 then bufnr = vim.api.nvim_get_current_buf() end - local id = vim.b[bufnr].inbox_id - - if id == nil then - return - end - if vim.b[bufnr].show_all_headers then vim.b[bufnr].show_all_headers = false else vim.b[bufnr].show_all_headers = true end - view.render_headers(bufnr, id) + view.render_headers(bufnr) +end + +---@return inbox.Entry? entry +function M.get_cursor_entry() + local id = M.get_cursor_id() + if id == nil then + vim.notify(("Failed to get entry with id: %s"):format(id), vim.log.levels.ERROR) + return nil + end + + return M.indexer.get_entry(id) end ---@return string? id @@ -120,28 +122,10 @@ function M.get_cursor_id() return id end ----@return inbox.Entry? entry -function M.get_cursor_entry() - local id = M.get_cursor_id() - if id == nil then - vim.notify(("Failed to get entry with id: %s"):format(id), vim.log.levels.ERROR) - return nil - end - - local indexers = require("inbox.indexers") - local indexer = indexers.get_indexer() - - return indexer.get_entry(id) -end - ---@param opts inbox.Config 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) + indexers.setup(config) for sign, value in pairs(config.flags) do local name = utils.sign_name(sign) diff --git a/lua/inbox/types.lua b/lua/inbox/types.lua index 4a7efe9..3913699 100644 --- a/lua/inbox/types.lua +++ b/lua/inbox/types.lua @@ -1,6 +1,5 @@ ----@class inbox.Config +---@class inbox.Config: inbox.Indexer.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 @@ -8,6 +7,17 @@ ---@field flags table ---@field headers inbox.HeaderKey[] +---@class inbox.Indexer +---@field setup? fun(opts: table) +---@field available? fun(): boolean +---@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[] + +---@class inbox.Indexer.Config +---@field indexer string|nil +---@field indexer_config table|nil + ---@class inbox.PartFilter ---@field command string ---@field args string[] @@ -24,18 +34,6 @@ ---| "text/html" ---| string ----@class inbox.Indexer ----@field setup? fun(opts: table) ----@field available? fun(): boolean ----@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[] - ----@alias inbox.Indexer.Config ----| "notmuch" ----| string ----| table - ---@class inbox.Summary ---@field tags string[] ---@field date string diff --git a/lua/inbox/utils.lua b/lua/inbox/utils.lua index e9826c8..d1e627c 100644 --- a/lua/inbox/utils.lua +++ b/lua/inbox/utils.lua @@ -5,30 +5,30 @@ local M = {} ---@field [2] string hl ---@param msg string ----@param vars table +---@param vars table? ---@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) + for name, value in pairs(vars or {}) do + string.format("%s\n%s: %s", msg, name, vim.inspect(value)) end vim.notify(msg, level, { title = "inbox.nvim" }) end ---@param msg string ----@param vars table +---@param vars table? function M.info(msg, vars) M.notify(msg, vars, vim.log.levels.INFO) end ---@param msg string ----@param vars table +---@param vars table? function M.warn(msg, vars) M.notify(msg, vars, vim.log.levels.WARN) end ---@param msg string ----@param vars table +---@param vars table? function M.error(msg, vars) M.notify(msg, vars, vim.log.levels.ERROR) end @@ -205,4 +205,15 @@ function M.stateful_iter(table, wrap) end end +---@param modname string +---@return any module +function M.try_require(modname) + local is_ok, result = pcall(require, modname) + if is_ok then + return result + else + error(string.format("Module not found: %s", modname)) + end +end + return M diff --git a/lua/inbox/view.lua b/lua/inbox/view.lua index a72f3f2..e204e70 100644 --- a/lua/inbox/view.lua +++ b/lua/inbox/view.lua @@ -76,8 +76,7 @@ end ---@param bufnr integer function M.render_inbox(bufnr, maildir) - local indexer = indexers.get_indexer() - indexer.index(maildir, function(ids, entries, signs) + indexers.get_indexer().index(maildir, function(ids, entries, signs) vim.b[bufnr].inbox_ids = ids local lines, highlights = utils.render_table(entries, config.columns) @@ -140,7 +139,7 @@ function M.initialize_entry(maildir, id, content_type) vim.b[bufnr].inbox_id = id vim.b[bufnr].header_filter = config.headers - M.render_headers(bufnr, id) + M.render_headers(bufnr) M.render_entry(bufnr, id, content_type) vim.api.nvim_create_autocmd({ "BufModifiedSet", "BufWinEnter" }, { @@ -165,9 +164,8 @@ function M.initialize_entry(maildir, id, content_type) return bufnr end -function M.render_headers(bufnr, id) - local indexer = indexers.get_indexer() - local entry = indexer.get_entry(id) +function M.render_headers(bufnr) + local entry = indexers.get_indexer().get_entry(vim.b[bufnr].inbox_id) if entry == nil then return @@ -210,8 +208,7 @@ 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) + local entry = indexers.get_indexer().get_entry(id) if entry == nil then utils.error("Failed to get entry", { id = id }) -- cgit v1.2.3-70-g09d2