Skip to content

Commit

Permalink
feat: display all suggestions in menu
Browse files Browse the repository at this point in the history
close #6
  • Loading branch information
f3fora committed Oct 3, 2022
1 parent 5602f1a commit 20f3347
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 10 deletions.
24 changes: 19 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,16 @@
## Setup

```lua
require('cmp').setup {
sources = {
{ name = 'spell' }
}
}
require('cmp').setup({
sources = {
{
name = 'spell',
option = {
keep_all_entries = false,
},
},
},
})
```

Setting `spell` (and `spelllang`) is mandatory to use `spellsuggest`.
Expand All @@ -19,6 +24,15 @@ vim.opt.spell = true
vim.opt.spelllang = { 'en_us' }
```

## Options

### `keep_all_entries`

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`

## Credit

- [compe-spell](https://github.com/hrsh7th/nvim-compe/blob/master/lua/compe_spell/init.lua)
Expand Down
57 changes: 52 additions & 5 deletions lua/cmp-spell/init.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
local source = {}

local defaults = {
keep_all_entries = false,
}

function source.new()
return setmetatable({}, { __index = source })
end
Expand All @@ -12,17 +16,60 @@ function source:get_keyword_pattern()
return [[\K\+]]
end

local function candidates(entries)
local function validate_option(params)
local option = vim.tbl_deep_extend('keep', params.option, defaults)
vim.validate({
keep_all_entries = { option.keep_all_entries, 'boolean' },
})
return option
end

local function number_to_text(input, number, len)
local loglen = math.ceil(math.log10(len + 1))
return string.format(input .. '%0' .. loglen .. 'd', number)
end

local function candidates(input, option)
local items = {}
local entries = vim.fn.spellsuggest(input)
local offset = 0
if vim.tbl_isempty(vim.spell.check(input)) then
offset = 1
items[offset] = {
label = input,
filterText = input,
insertText = input,
-- add a
sortText = number_to_text(input, offset, #entries + offset),
-- If the current word is spelled correctly, preselect it.
preselect = true,
}
end
for k, v in ipairs(entries) do
items[k] = { label = v }
items[k + offset] = {
label = v,
-- Using the `input` word as filterText, all suggestions are displayed in completion menu.
filterText = option.keep_all_entries and input or v,
insertText = v,
-- To keep the order of suggestions, add the index at the end of sortText and trick the compare algorithms.
-- TODO: Add a custom compare function.
sortText = option.keep_all_entries and number_to_text(input, k + offset, #entries + offset) or v,
preselect = false,
}
end
return items
end

function source:complete(request, callback)
local input = string.sub(request.context.cursor_before_line, request.offset)
callback({ items = candidates(vim.fn.spellsuggest(input)), isIncomplete = true })
function source:complete(params, callback)
local option = validate_option(params)

local input = string.sub(params.context.cursor_before_line, params.offset)
callback({ items = candidates(input, option), isIncomplete = true })
end

local debug_name = 'spell'
function source:get_debug_name()
return debug_name
end

return source

0 comments on commit 20f3347

Please sign in to comment.