spell
source for nvim-cmp
based on vim's spellsuggest
.
cmp-spell
optionally supports dictionary definitions in the documentation window of nvim-cmp
.
These are the configuration default values.
require('cmp').setup({
sources = {
{
name = 'spell',
option = {
keep_all_entries = false,
enable_in_context = function()
return true
end,
definition = {
enable = false,
command = { "" },
format = function(_) end
}
},
},
},
})
Setting spell
(and spelllang
) is mandatory to use spellsuggest
.
vim.opt.spell = true
vim.opt.spelllang = { 'en_us' }
If true, all vim.fn.spellsuggest
results are displayed in nvim-cmp
menu. Otherwise, they are being filtered to only include fuzzy matches.
Type: boolean
Default: false
'nvim-cmp' menu is populated only when the function returns true.
For example, one can enable this source only when in a @spell
treesitter capture. See :help treesitter-highlight-spell
.
enable_in_context = function()
return require('cmp.config.context').in_treesitter_capture('spell')
end,
Type: function
Return: boolean
Default:
enable_in_context = function()
return true
end,
Note: this option will be removed when hrsh7th/nvim-cmp#632 is implemented.
These options are related to what is shown in the documentation window for each item.
If true, definitions for each entry are displayed by running an arbitrary
command (definition.command
) that retrieves them.
Type: boolean
Default: false
This is the external command to run and retrieve the definition of the word.
The field ${word}
will be replaced by the actual selected completion item.
Type: table of strings
Default: { "" }
For example, use WordNet for a free dictionary
command = { "wn", "${word}, "-over" }
or sdcv if you have StarDict dictionaries, maybe using goldendict.
command = { "sdcv", "-j", "-n", "${word}"},
A function to format the output of definition.command
before showing it in
the documentation window.
Type: function
Parameter: Table with the output lines of definition.command
Return: Text string to display in the documentation window
Default: function(_) end
For example, if you are using the WordNet example above, the corresponding format function would be
format = function(text) return table.concat(text, "\n") end
And if you are using StarDict dictionaries and want to output Markdown from the json data, the format function could be something like this:
format = function (text)
local md = {}
local data = vim.fn.json_decode(text)
if data ~= nil then
for _, v in ipairs(data) do
table.insert(md, "# Dictionary: " .. v['dict'] .. "\n")
table.insert(md, "## Word: " .. v['word'])
local definition = v['definition']
-- Remove html tags
definition = string.gsub(definition, "<.+>", "")
-- Remove reference to pronunciation WAV files
definition = string.gsub(definition, "[^%s]*%.wav%s", "")
-- Swap [] for italics
definition = string.gsub(definition, "%[([^%]]+)%]", "*%1*")
table.insert(md, definition .. "\n\n")
end
end
return table.concat(md)
end
This example configures cmp-spell
to query definitions from WordNet:
require('cmp').setup({
sources = {
name = 'spell',
keyword_length = 2,
max_item_count = 8,
option = {
-- if this is set to false, fuzzy matching will discard most of
-- the spelling suggestions, even if they are correct
keep_all_entries = true,
definition = {
enable = true,
command = { "wn", "${word}", "-over" },
format = function(text) return table.concat(text, "\n") end
}
}
}
})
Or to get definitions from your StarDict dictionaries and convert them into a simplified Markdown format you can display in the documentation window:
local function format_spell_definition(text)
local md = {}
local data = vim.fn.json_decode(text)
if data ~= nil then
for _, v in ipairs(data) do
table.insert(md, "# Dictionary: " .. v['dict'] .. "\n")
table.insert(md, "## Word: " .. v['word'])
local definition = v['definition']
-- Remove html tags
definition = string.gsub(definition, "<.+>", "")
-- Remove reference to pronunciation WAV files
definition = string.gsub(definition, "[^%s]*%.wav%s", "")
-- Swap [] for italics
definition = string.gsub(definition, "%[([^%]]+)%]", "*%1*")
table.insert(md, definition .. "\n\n")
end
end
return table.concat(md)
end
require('cmp').setup({
sources = {
name = 'spell',
keyword_length = 2,
max_item_count = 8,
option = {
-- if this is set to false, fuzzy matching will discard most of
-- the spelling suggestions, even if they are correct
keep_all_entries = true,
definition = {
enable = true,
command = { "sdcv", "-j", "-n", "${word}"},
format = format_spell_definition,
}
}
}
}
})