From eee9ce71bd0e84859e5d3a5135fe4f4265d331da Mon Sep 17 00:00:00 2001 From: Toby Vincent Date: Sat, 21 Oct 2023 21:47:26 -0500 Subject: feat: parse full headers This manually parses the headers from message. It complicates both parsing and displaying the headers. --- lua/inbox/config.lua | 2 ++ lua/inbox/indexers/notmuch.lua | 9 +++++++++ lua/inbox/types.lua | 2 +- lua/inbox/utils.lua | 30 ++++++++++++++++++++++++++++++ lua/inbox/view.lua | 23 +++++++++++++++-------- 5 files changed, 57 insertions(+), 9 deletions(-) diff --git a/lua/inbox/config.lua b/lua/inbox/config.lua index 634b35d..2f7f47d 100644 --- a/lua/inbox/config.lua +++ b/lua/inbox/config.lua @@ -1,3 +1,5 @@ +local utils = require("inbox.utils") + ---@type inbox.Config local default_config = { indexer_config = "notmuch", diff --git a/lua/inbox/indexers/notmuch.lua b/lua/inbox/indexers/notmuch.lua index a05c112..a06991a 100644 --- a/lua/inbox/indexers/notmuch.lua +++ b/lua/inbox/indexers/notmuch.lua @@ -157,6 +157,15 @@ function M.show_id(id) entry = entry[1] --[[@as inbox.Notmuch.Entry]] end + job = Job:new({ + command = "notmuch", + args = { "show", "--part=0", ("id:%s"):format(id) }, + }) + + local lines = job:sync() + 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 diff --git a/lua/inbox/types.lua b/lua/inbox/types.lua index a4105b0..4a7efe9 100644 --- a/lua/inbox/types.lua +++ b/lua/inbox/types.lua @@ -48,7 +48,7 @@ ---@field filename string[] ---@field tags string[] ---@field parts inbox.EntryPart[] ----@field headers table +---@field headers table ---@class inbox.EntryPart ---@field id integer diff --git a/lua/inbox/utils.lua b/lua/inbox/utils.lua index 8d82b7d..e9826c8 100644 --- a/lua/inbox/utils.lua +++ b/lua/inbox/utils.lua @@ -150,6 +150,36 @@ function M.json_decode(json) return results end +---@param lines string[] +---@return table headers +function M.parse_headers(lines) + local headers = {} + + local cur_header + for _, line in pairs(lines) do + if line == "" then + break + end + + local header, value = line:match("^([A-Z][^: ]*): (.*)") + + if header then + cur_header = header + headers[cur_header] = {} + else + value = line + end + + if cur_header then + table.insert(headers[cur_header], value) + else + M.error("Failed to parse line in headers", { line = line }) + end + end + + return headers +end + ---@param bufnr integer ---@return string? maildir maildir name ---@return string? id entry id diff --git a/lua/inbox/view.lua b/lua/inbox/view.lua index 3ba20c6..a72f3f2 100644 --- a/lua/inbox/view.lua +++ b/lua/inbox/view.lua @@ -175,17 +175,24 @@ function M.render_headers(bufnr, id) local lines = {} - for _, name in pairs(config.headers) do - if entry.headers[name] ~= nil then - table.insert(lines, ("%s: %s"):format(name, entry.headers[name])) + local headers = {} + if vim.b[bufnr].show_all_headers then + headers = entry.headers + else + for _, name in pairs(config.headers) do + if entry.headers[name] ~= nil then + headers[name] = entry.headers[name] + end end end - if vim.b[bufnr].show_all_headers then - for name, value in pairs(entry.headers) do - if not vim.tbl_contains(config.headers, name) then - table.insert(lines, ("%s: %s"):format(name, value)) - end + for name, value in pairs(headers) do + local i, line = next(value) + table.insert(lines, ("%s: %s"):format(name, line)) + i, line = next(value, i) + while i ~= nil do + table.insert(lines, line) + i, line = next(value, i) end end -- cgit v1.2.3-70-g09d2