From b69ee5088114802c56729f1ee09e11fdca88b845 Mon Sep 17 00:00:00 2001 From: Christian Segundo Date: Sun, 8 Dec 2024 11:40:50 +0100 Subject: First commit --- README.md | 38 +++++++++++++++++ after/plugin/cmp_abook.lua | 1 + lua/cmp_abook/init.lua | 99 +++++++++++++++++++++++++++++++++++++++++++++ preview.gif | Bin 0 -> 301495 bytes 4 files changed, 138 insertions(+) create mode 100644 README.md create mode 100644 after/plugin/cmp_abook.lua create mode 100644 lua/cmp_abook/init.lua create mode 100644 preview.gif diff --git a/README.md b/README.md new file mode 100644 index 0000000..007de42 --- /dev/null +++ b/README.md @@ -0,0 +1,38 @@ +# cmp-abook + +A completion source for [nvim-cmp][nvim-cmp] that provides sources for addresses +in [Abook][abook] when writing emails. + +![](preview.gif) + +## Dependencies + +- [plenary.nvim][plenary.nvim] + +## Setup + +Just add the `abook` source to [nvim-cmp][nvim-cmp] setup call: + +``` lua +sources = { + -- Most names in an address book have spaces in them. However, cmp restarts + -- the completion after a space. The `space_filter` option is a way to get + -- around this by using a different character to represent spaces. + { name = "abook", option = { space_filter = "-" } } +} +``` + +### Multiple addressbooks + +By default the plugin uses the default addressbook. You can use the +`ABOOK_ADDRESSBOOK` environment variable option to control which addressbook to +use. If you're using `mutt` for email, you could set it like this: + +``` +set editor="ABOOK_ADDRESSBOOK='$HOME/.config/abook/my_custom_addressbook' nvim ...other options... %s" +``` + +--- +[plenary.nvim]: https://github.com/nvim-lua/plenary.nvim +[abook]: https://abook.sourceforge.io/ +[nvim-cmp]: https://github.com/hrsh7th/nvim-cmp diff --git a/after/plugin/cmp_abook.lua b/after/plugin/cmp_abook.lua new file mode 100644 index 0000000..a5bf249 --- /dev/null +++ b/after/plugin/cmp_abook.lua @@ -0,0 +1 @@ +require('cmp').register_source('abook', require('cmp_abook').new()) 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 diff --git a/preview.gif b/preview.gif new file mode 100644 index 0000000..771d0a4 Binary files /dev/null and b/preview.gif differ -- cgit v1.2.3