aboutsummaryrefslogtreecommitdiff
path: root/lua/cmp_abook
diff options
context:
space:
mode:
Diffstat (limited to 'lua/cmp_abook')
-rw-r--r--lua/cmp_abook/init.lua99
1 files changed, 99 insertions, 0 deletions
diff --git a/lua/cmp_abook/init.lua b/lua/cmp_abook/init.lua
new file mode 100644
index 0000000..0388b60
--- /dev/null
+++ b/lua/cmp_abook/init.lua
@@ -0,0 +1,99 @@
+local has_cmp, cmp = pcall(require, "cmp")
+if not has_cmp then
+ return
+end
+
+local has_job, Job = pcall(require, "plenary.job")
+if not has_job then
+ return
+end
+
+local source = {}
+local defaults = {
+ space_filter = "-",
+ address_book = nil,
+}
+
+source.new = function()
+ return setmetatable({}, { __index = source })
+end
+
+function source:is_available()
+ return vim.bo.filetype == "mail"
+end
+function source:get_debug_name()
+ return "abook"
+end
+
+function source:complete(params, callback)
+ params.option = vim.tbl_deep_extend("keep", params.option, defaults)
+ vim.validate(
+ "params.option.space_filter",
+ params.option.space_filter,
+ { "string" }
+ )
+
+ local ctx = params.context
+
+ if
+ not (
+ ctx.cursor_line:match("^To: ")
+ or ctx.cursor_line:match("^Cc: ")
+ or ctx.cursor_line:match("^Bcc: ")
+ )
+ then
+ callback({})
+ return
+ end
+
+ local query = ""
+ local line = ctx.cursor_line
+ local cursor = ctx.cursor.character
+ for i = cursor, 1, -1 do
+ local char = line:sub(i, i)
+ if char == ":" or char == "," then
+ query = line:sub(i + 2, cursor)
+ break
+ end
+ end
+
+ local abook_addressbook = os.getenv("ABOOK_ADDRESSBOOK")
+ local abook_args = { "--mutt-query", query }
+ if abook_addressbook then
+ table.insert(abook_args, "-f")
+ table.insert(abook_args, abook_addressbook)
+ end
+
+ Job
+ :new({
+ command = "abook",
+ args = abook_args,
+ on_exit = function(job, code)
+ if code ~= 0 then
+ return
+ end
+
+ local result = job:result()
+
+ local items = {}
+ for _, item in ipairs(result) do
+ local item_parts = vim.split(item, "\t", { trimempty = true })
+ local label = string.format(
+ "%s <%s>",
+ item_parts[2],
+ item_parts[1]
+ ) or item_parts[1]
+ table.insert(items, {
+ label = label,
+ filterText = label:gsub(" ", params.option.space_filter),
+ kind = cmp.lsp.CompletionItemKind.Text,
+ })
+ end
+
+ callback({ items = items, isIncomplete = false })
+ end,
+ })
+ :start()
+end
+
+return source