aboutsummaryrefslogtreecommitdiff
path: root/lua/cmp_abook/init.lua
blob: adcfbc8402d91ded8f886ad428496f7c14ac6e1b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
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 })
               if item_parts[1] then
                 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
            end

            callback({ items = items, isIncomplete = false })
         end,
      })
      :start()
end

return source