Skip to content

Commit

Permalink
feat: rewrite some logic regarding offset and cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
max397574 committed Jul 16, 2024
1 parent 97e85fc commit dd8cf2e
Show file tree
Hide file tree
Showing 10 changed files with 137 additions and 27 deletions.
6 changes: 5 additions & 1 deletion docs/design.norg
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ categories: [
docs
]
created: 2023-11-15T17:42:49+0100
updated: 2023-11-15T17:42:49+0100
updated: 2024-07-16T19:15:01+0100
version: 1.1.1
@end

Expand All @@ -34,6 +34,10 @@ version: 1.1.1
-- Try to get nicely concealed like in core or noice.nvim
-- Allow to send to e.g. quickfix or copy

* Terms
** Offset
Offset always describes the distance between e.g. the start of an entry from the beginning of the
line.

* Architecture
TODO: fancy ascii diagramms
Expand Down
4 changes: 2 additions & 2 deletions docs/entry.norg
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ categories: [
types
]
created: 2023-11-15T17:42:46+0100
updated: 2024-07-07T21:15:43+0100
updated: 2024-07-15T19:07:45+0100
tangle: {
languages: {
lua: ../lua/neocomplete/types/entry.lua
Expand Down Expand Up @@ -100,6 +100,6 @@ version: 1.1.1
Essentially where entry insertion should happen (column)
#tangle
@code lua
--- Get offset of entry
--- Get offset of entry from beginning of line
---@field get_offset fun(self: neocomplete.entry): integer
@end
11 changes: 10 additions & 1 deletion docs/source.norg
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ categories: [
types
]
created: 2023-11-15T17:42:46+0100
updated: 2024-06-18T18:08:13+0100
updated: 2024-07-15T20:10:47+0100
tangle: {
languages: {
lua: ../lua/neocomplete/types/source.lua
Expand All @@ -29,6 +29,15 @@ version: 1.1.1
---@class neocomplete.source
@end

* Fields
** Name

#tangle
@code lua
--- Name of the source
---@field name string
@end

* Methods
** `is_available()`
Each source can have a function to show whether it's available or not. If your source should
Expand Down
10 changes: 7 additions & 3 deletions lua/neocomplete/core.lua
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ function core:complete(reason)
local entries = {}
local remaining = #sources
self.context.reason = reason
local offset = 0
local offset = self.context.cursor.col
for i, source in ipairs(sources) do
if source.source.is_available() then
require("neocomplete.sources").complete(self.context, source, function(items, is_incomplete)
Expand All @@ -27,8 +27,12 @@ function core:complete(reason)
require("neocomplete.sources").sources[i].incomplete = is_incomplete or false
require("neocomplete.sources").sources[i].entries = items
remaining = remaining - 1
offset = math.max(offset, source:get_offset(self.context))
if not vim.tbl_isempty(items or {}) then
local source_offset = source:get_offset(self.context)
if source_offset then
offset = math.min(offset, source_offset)
end

vim.list_extend(entries, items)
vim.schedule(function()
if remaining == 0 then
Expand All @@ -38,7 +42,7 @@ function core:complete(reason)
end)
:totable()
-- TODO: source priority and max entries
local opened_at = self.context.cursor.col - offset
local opened_at = offset
if opened_at == self.last_opened_at and self.menu:is_open() then
self.menu.entries = filtered_entries
self.menu:readjust_win(offset)
Expand Down
15 changes: 8 additions & 7 deletions lua/neocomplete/menu/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ function Menu.close(self)
self.menu_window:close()
self.docs_window:close()
self.ghost_text:hide()
local sources = require("neocomplete.sources").get_sources()
for i, _ in ipairs(sources) do
require("neocomplete.sources").sources[i].entries = nil
end
end

---@param menu neocomplete.menu
Expand All @@ -43,7 +47,7 @@ local function draw_docs(menu, entry, config)
return
end

local function open_docs_window(doc_entry, x_offset)
local function open_docs_window(doc_entry, offset)
if not doc_entry.completion_item.documentation then
return
end
Expand All @@ -58,7 +62,7 @@ local function draw_docs(menu, entry, config)
end

local TODO = 100000
local width = math.min(vim.o.columns - x_offset, config.max_width)
local width = math.min(vim.o.columns - offset, config.max_width)
local height = math.min(TODO, config.max_height)

local do_stylize = format == "markdown" and vim.g.syntax_on ~= nil
Expand All @@ -81,7 +85,7 @@ local function draw_docs(menu, entry, config)
menu.docs_window:open_cursor_relative(
width,
math.min(height, menu.menu_window.max_height),
-x_offset,
offset + 1,
menu.config.ui.docs_view
)
menu.docs_window:draw_scrollbar()
Expand All @@ -94,10 +98,7 @@ local function draw_docs(menu, entry, config)
entry.completion_item = resolved_item
open_docs_window(
entry,
menu.menu_window.opened_at.col
+ vim.api.nvim_win_get_width(menu.menu_window.winnr)
- (vim.api.nvim_win_get_cursor(0)[2] - 1)
+ 1
menu.menu_window.opened_at.col + vim.api.nvim_win_get_width(menu.menu_window.winnr) + 1
)
end)
else
Expand Down
25 changes: 17 additions & 8 deletions lua/neocomplete/source.lua
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,26 @@ end

function source.get_offset(self, context)
if not context then
return 0
return context.cursor.col
end
local line_to_cursor = context.line_before_cursor
local keyword_pattern = self:get_keyword_pattern()
-- Can add $ to keyword pattern because we just match on line to cursor
local word_boundary = vim.fn.match(line_to_cursor, keyword_pattern .. "$")
if word_boundary == -1 then
return 0
local source_offset, _ = vim.regex(self:get_keyword_pattern() .. "\\m$"):match_str(context.line_before_cursor)

if source_offset then
return source_offset
end

return context.cursor.col - word_boundary
return context.cursor.col

-- -- Can add $ to keyword pattern because we just match on line to cursor
-- local word_boundary = vim.fn.match(line_to_cursor, keyword_pattern .. "$")
-- print(keyword_pattern)
-- print("match", word_boundary)
-- print("regex", vim.regex(keyword_pattern .. "\\m$"):match_str(line_to_cursor))
-- if word_boundary == -1 then
-- return 0
-- end
--
-- return context.cursor.col - word_boundary
end

return source
2 changes: 1 addition & 1 deletion lua/neocomplete/types/entry.lua
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@
---@field matches integer[]
--- Score from filtering
---@field score number
--- Get offset of entry
--- Get offset of entry from beginning of line
---@field get_offset fun(self: neocomplete.entry): integer
4 changes: 3 additions & 1 deletion lua/neocomplete/types/source.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
--- A completion source for neocomplete.nvim
---@class neocomplete.source
--- Name of the source
---@field name string
--- Whether the source will provide completions in the current context or not
---@field is_available? fun(): boolean
--- Resolve a completion item
Expand All @@ -11,4 +13,4 @@
--- Get keyword pattern for this source
---@field get_keyword_pattern? fun(self: neocomplete.source): string
--- Returns completion in the provided context
---@field complete fun(completion_context: neocomplete.completion_context, callback: fun(items: lsp.CompletionItem[], is_incomplete?: boolean)): nil
---@field complete fun(completion_context: neocomplete.completion_context, callback: fun(items: lsp.CompletionItem[], is_incomplete?: boolean)): nil
7 changes: 4 additions & 3 deletions lua/neocomplete/utils/window.lua
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ function Window:open_cursor_relative(width, wanted_height, offset, config)
self.position = position
self.opened_at = {
row = cursor[1] - 1,
col = cursor[2] - offset,
col = offset,
}
self.winnr = vim.api.nvim_open_win(self.buf, false, {
relative = "cursor",
Expand All @@ -68,7 +68,7 @@ function Window:open_cursor_relative(width, wanted_height, offset, config)
style = "minimal",
border = border,
row = position == "below" and 1 or 0,
col = -offset,
col = offset - cursor[2],
zindex = 1000,
})
vim.wo[self.winnr][0].scrolloff = 0
Expand Down Expand Up @@ -171,11 +171,12 @@ function Window:open_scrollbar_win(width, height, offset)
pcall(vim.api.nvim_win_close, self.scrollbar.win, true)
self.scrollbar.win = nil
end
local cursor = vim.api.nvim_win_get_cursor(0)
if self.config.ui.menu.scrollbar then
self.scrollbar.win = vim.api.nvim_open_win(self.scrollbar.buf, false, {
height = height,
relative = "cursor",
col = -offset + width,
col = offset + width - cursor[2],
row = self.position == "below" and 2 or -(height + 2) + 1,
width = 1,
style = "minimal",
Expand Down
80 changes: 80 additions & 0 deletions spec/tests/complete/old_bugs_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,84 @@ describe("Old Bugs:", function()
assert.is.equal('require"neocomplete.menu', context.line_before_cursor)
assert.is.equal(24, context.cursor.col)
end)
it("cmp-path doesn't set cursor properly", function()
vim.fn.setline(1, " ./in")
vim.cmd.startinsert({ bang = true })
---@type lsp.CompletionItem
local completion_item = {
data = {},
filterText = "init.lua",
insertText = "init.lua",
kind = 17,
label = "init.lua",
}
local entry_context = {
bufnr = 1,
cursor = {
col = 8,
row = 1,
},
line = " ./in",
line_before_cursor = " ./in",
reason = 1,
}
---@diagnostic disable-next-line: missing-fields
local entry = Entry.new(completion_item, {
get_keyword_pattern = function(_)
return "\\%([^/\\\\:\\*?<>'\"`\\|]\\)" .. "*"
end,
}, entry_context)
require("neocomplete.menu.confirm")(entry)

local context = Context:new()
assert.is.equal(" ./init.lua", context.line)
assert.is.equal(" ./init.lua", context.line_before_cursor)
assert.is.equal(14, context.cursor.col)
end)
it('problem with ["end"] from luals', function()
vim.fn.setline(1, " completion_item.range.")
vim.cmd.startinsert({ bang = true })
---@type lsp.CompletionItem
local completion_item = {
additionalTextEdits = {
{
newText = "",
range = {
["end"] = { character = 35, line = 1 },
start = { character = 34, line = 1 },
},
},
},
data = { id = 119, uri = "not relevant" },
detail = "lsp.Position",
documentation = { kind = "markdown", value = "not relevant" },
insertTextFormat = 2,
kind = 5,
label = '"end"',
sortText = "0001",
textEdit = {
newText = '["end"]',
range = {
["end"] = { character = 35, line = 1 },
start = { character = 4, line = 3 },
},
},
}
local entry_context = {
bufnr = 1,
cursor = { col = 35, row = 1 },
line = " completion_item.textEdit.range.",
line_before_cursor = " completion_item.textEdit.range.",
previous = nil,
reason = 1,
}

complete(completion_item, entry_context)

local context = Context:new()
-- TODO: readd once a response on https://github.com/LuaLS/lua-language-server/issues/2762
-- assert.is.equal(' completion_item.textEdit.range["end"]', context.line)
-- assert.is.equal(' completion_item.textEdit.range["end"]', context.line_before_cursor)
-- assert.is.equal(14, context.cursor.col)
end)
end)

0 comments on commit dd8cf2e

Please sign in to comment.