Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nuke the debt #389

Merged
merged 5 commits into from
Nov 27, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
504 changes: 269 additions & 235 deletions README.md

Large diffs are not rendered by default.

6 changes: 0 additions & 6 deletions lua/blink/cmp/accept/brackets/init.lua

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
local text_edits_lib = require('blink.cmp.accept.text-edits')
local brackets_lib = require('blink.cmp.accept.brackets')
local text_edits_lib = require('blink.cmp.lib.text_edits')
local brackets_lib = require('blink.cmp.completion.brackets')

--- Applies a completion item to the current buffer
--- @param ctx blink.cmp.Context
--- @param item blink.cmp.CompletionItem
local function accept(ctx, item)
--- @param callback fun()
local function accept(ctx, item, callback)
local sources = require('blink.cmp.sources.lib')
require('blink.cmp.trigger.completion').hide()
require('blink.cmp.completion.trigger').hide()

-- let the source execute the item itself if it indicates it can
if sources.should_execute(item) then
sources.execute(ctx, item)
callback()
return
end

Expand Down Expand Up @@ -66,12 +68,14 @@ local function accept(ctx, item)
-- TODO: since we apply the additional text edits after, auto imported functions will not
-- get auto brackets. If we apply them before, we have to modify the textEdit to compensate
brackets_lib.add_brackets_via_semantic_token(vim.bo.filetype, item, function()
require('blink.cmp.trigger.completion').show_if_on_trigger_character({ is_accept = true })
require('blink.cmp.trigger.signature').show_if_on_trigger_character()
require('blink.cmp.completion.trigger').show_if_on_trigger_character({ is_accept = true })
require('blink.cmp.signature.trigger').show_if_on_trigger_character()
callback()
end)
else
require('blink.cmp.trigger.completion').show_if_on_trigger_character({ is_accept = true })
require('blink.cmp.trigger.signature').show_if_on_trigger_character()
require('blink.cmp.completion.trigger').show_if_on_trigger_character({ is_accept = true })
require('blink.cmp.signature.trigger').show_if_on_trigger_character()
callback()
end

-- Notify the rust module that the item was accessed
Expand Down
58 changes: 58 additions & 0 deletions lua/blink/cmp/completion/accept/prefix.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
local PAIRS_AND_INVALID_CHARS = {}
string.gsub('\'"=$()[]<>{} \t\n\r', '.', function(char) PAIRS_AND_INVALID_CHARS[string.byte(char)] = true end)

local CLOSING_PAIR = {
[string.byte('<')] = string.byte('>'),
[string.byte('[')] = string.byte(']'),
[string.byte('(')] = string.byte(')'),
[string.byte('{')] = string.byte('}'),
[string.byte('"')] = string.byte('"'),
[string.byte("'")] = string.byte("'"),
}

local ALPHANUMERIC = {}
string.gsub(
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789',
'.',
function(char) ALPHANUMERIC[string.byte(char)] = true end
)

--- Gets the prefix of the given text, stopping at brackets and quotes
--- @param text string
--- @return string
local function get_prefix_before_brackets_and_quotes(text)
local closing_pairs_stack = {}
local word = ''

local add = function(char)
word = word .. string.char(char)

-- if we've seen the opening pair, and we've just received the closing pair,
-- remove it from the closing pairs stack
if closing_pairs_stack[#closing_pairs_stack] == char then
table.remove(closing_pairs_stack, #closing_pairs_stack)
-- if the character is an opening pair, add it to the closing pairs stack
elseif CLOSING_PAIR[char] ~= nil then
table.insert(closing_pairs_stack, CLOSING_PAIR[char])
end
end

local has_alphanumeric = false
for i = 1, #text do
local char = string.byte(text, i)
if PAIRS_AND_INVALID_CHARS[char] == nil then
add(char)
has_alphanumeric = has_alphanumeric or ALPHANUMERIC[char]
elseif not has_alphanumeric or #closing_pairs_stack ~= 0 then
add(char)
-- if we had an alphanumeric, and the closing pairs stuck *just* emptied,
Saghen marked this conversation as resolved.
Show resolved Hide resolved
-- because the current character is a closing pair, we exit
if has_alphanumeric and #closing_pairs_stack == 0 then break end
else
break
end
end
return word
end

return get_prefix_before_brackets_and_quotes
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
--- @param item blink.cmp.CompletionItem
local function preview(item)
local text_edits_lib = require('blink.cmp.accept.text-edits')
local text_edits_lib = require('blink.cmp.lib.text_edits')
local text_edit = text_edits_lib.get_from_item(item)

if item.insertTextFormat == vim.lsp.protocol.InsertTextFormat.Snippet then
local expanded_snippet = require('blink.cmp.sources.snippets.utils').safe_parse(text_edit.newText)
text_edit.newText = require('blink.cmp.utils').get_prefix_before_brackets_and_quotes(
expanded_snippet and tostring(expanded_snippet) or text_edit.newText
)
local snippet = expanded_snippet and tostring(expanded_snippet) or text_edit.newText
local get_prefix_before_brackets_and_quotes = require('blink.cmp.completion.accept.prefix')
text_edit.newText = get_prefix_before_brackets_and_quotes(snippet)
end

local undo_text_edit = text_edits_lib.get_undo_text_edit(text_edit)
Expand Down
6 changes: 6 additions & 0 deletions lua/blink/cmp/completion/brackets/init.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
local brackets = {}

brackets.add_brackets = require('blink.cmp.completion.brackets.kind')
brackets.add_brackets_via_semantic_token = require('blink.cmp.completion.brackets.semantic')

return brackets
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
local config = require('blink.cmp.config').accept.auto_brackets
local utils = require('blink.cmp.accept.brackets.utils')
local utils = require('blink.cmp.completion.brackets.utils')

--- @param filetype string
--- @param item blink.cmp.CompletionItem
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
local config = require('blink.cmp.config').accept.auto_brackets
local utils = require('blink.cmp.accept.brackets.utils')
local config = require('blink.cmp.config').completion.accept.auto_brackets
local utils = require('blink.cmp.completion.brackets.utils')

local semantic = {}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
local config = require('blink.cmp.config').accept.auto_brackets
local brackets = require('blink.cmp.accept.brackets.config')
local config = require('blink.cmp.config').completion.accept.auto_brackets
local brackets = require('blink.cmp.completion.brackets.config')
local utils = {}

--- @param snippet string
Expand Down
67 changes: 67 additions & 0 deletions lua/blink/cmp/completion/init.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
local config = require('blink.cmp.config')
local completion = {}

function completion.setup()
-- trigger controls when to show the window and the current context for caching
local trigger = require('blink.cmp.completion.trigger')
trigger.activate()

-- sources fetch completion items and documentation
local sources = require('blink.cmp.sources.lib')

-- manages the completion list state:
-- fuzzy matching items
-- when to show/hide the windows
-- selection
-- accepting and previewing items
local list = require('blink.cmp.completion.list')

-- trigger -> sources: request completion items from the sources on show
trigger.show_emitter:on(function(event) sources.request_completions(event.context) end)
trigger.hide_emitter:on(function()
sources.cancel_completions()
list.hide()
end)

-- sources -> list
sources.completions_emitter:on(function(event)
-- schedule for later to avoid adding 0.5-4ms to insertion latency
vim.schedule(function()
-- since this was performed asynchronously, we check if the context has changed
if trigger.context == nil or event.context.id ~= trigger.context.id then return end
list.show(event.context, event.items)
end)
end)

--- list -> windows: ghost text and completion menu
-- setup completion menu
if config.completion.menu.enabled then
list.show_emitter:on(
function(event) require('blink.cmp.completion.windows.menu').open_with_items(event.context, event.items) end
)
list.hide_emitter:on(function() require('blink.cmp.completion.windows.menu').close() end)
list.select_emitter:on(function(event)
require('blink.cmp.completion.windows.menu').set_selected_item_idx(event.idx)
if config.completion.documentation.auto_show then
require('blink.cmp.completion.windows.documentation').auto_show_item(event.context, event.item)
end
end)
end

-- setup ghost text
if config.completion.ghost_text.enabled then
list.select_emitter:on(
function(event) require('blink.cmp.completion.windows.ghost_text').show_preview(event.item) end
)
list.hide_emitter:on(function() require('blink.cmp.completion.windows.ghost_text').clear_preview() end)
end

-- run 'resolve' on the item ahead of time to avoid delays
-- when accepting the item or showing documentation
list.select_emitter:on(function(event)
if event.item == nil then return end
require('blink.cmp.completion.prefetch')(event.context, event.item)
end)
end

return completion
Loading