Skip to content

Commit ad9ba28

Browse files
committed
feat: consolidate context table
1 parent 82106a4 commit ad9ba28

File tree

7 files changed

+42
-68
lines changed

7 files changed

+42
-68
lines changed

lua/blink/cmp/sources/buffer.lua

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ local buffer = {}
6666

6767
function buffer.new(config) return setmetatable(config, { __index = buffer }) end
6868

69-
function buffer:get_completions(context, callback)
69+
function buffer:get_completions(_, callback)
7070
local transformed_callback = function(items)
7171
callback({ is_incomplete_forward = false, is_incomplete_backward = false, items = items })
7272
end

lua/blink/cmp/sources/lib/context.lua

+8-10
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
local async = require('blink.cmp.sources.lib.async')
22
local sources_context = {}
33

4-
--- @param context blink.cmp.ShowContext
4+
--- @param context blink.cmp.Context
55
--- @param sources_groups blink.cmp.Source[][]
6-
--- @param on_completions_callback fun(context: blink.cmp.ShowContext, items: blink.cmp.CompletionItem[])
6+
--- @param on_completions_callback fun(context: blink.cmp.Context, items: blink.cmp.CompletionItem[])
77
function sources_context.new(context, sources_groups, on_completions_callback)
88
local self = setmetatable({}, { __index = sources_context })
99
self.id = context.id
@@ -12,7 +12,7 @@ function sources_context.new(context, sources_groups, on_completions_callback)
1212
self.active_request = nil
1313
self.queued_request_context = nil
1414
self.last_successful_completions = nil
15-
--- @type fun(context: blink.cmp.ShowContext, items: blink.cmp.CompletionItem[])
15+
--- @type fun(context: blink.cmp.Context, items: blink.cmp.CompletionItem[])
1616
self.on_completions_callback = on_completions_callback
1717

1818
return self
@@ -21,16 +21,14 @@ end
2121
--- @return blink.cmp.CompletionItem[]
2222
function sources_context:get_last_successful_completions() return self.last_successful_completions end
2323

24-
--- @param context blink.cmp.ShowContext
24+
--- @param context blink.cmp.Context
2525
function sources_context:get_completions(context)
2626
assert(context.id == self.id, 'Requested completions on a sources context with a different context ID')
2727

2828
if self.active_request ~= nil and self.active_request.status == async.STATUS.RUNNING then
29-
-- vim.print(tostring(context.id) .. ': queued request | col: ' .. context.bounds.end_col)
3029
self.queued_request_context = context
3130
return
3231
end
33-
-- vim.print(tostring(context.id) .. ': running request | col: ' .. context.bounds.end_col)
3432

3533
-- Create a task to get the completions for the first sources group,
3634
-- falling back to the next sources group iteratively if there are no items
@@ -62,19 +60,19 @@ function sources_context:get_completions(context)
6260
end
6361

6462
--- @param sources_group blink.cmp.Source[]
65-
--- @param context blink.cmp.ShowContext
63+
--- @param context blink.cmp.Context
6664
--- @return blink.cmp.Task
6765
function sources_context:get_completions_for_group(sources_group, context)
6866
-- get completions for each source in the group
6967
local tasks = vim.tbl_map(function(source)
7068
-- the source indicates we should refetch when this character is typed
71-
local trigger_character = context.trigger_character
72-
and vim.tbl_contains(source:get_trigger_characters(), context.trigger_character)
69+
local trigger_character = context.trigger.character
70+
and vim.tbl_contains(source:get_trigger_characters(), context.trigger.character)
7371

7472
-- The TriggerForIncompleteCompletions kind is handled by the source itself
7573
local source_context = vim.fn.deepcopy(context)
7674
source_context.trigger = trigger_character
77-
and { kind = vim.lsp.protocol.CompletionTriggerKind.TriggerCharacter, character = context.trigger_character }
75+
and { kind = vim.lsp.protocol.CompletionTriggerKind.TriggerCharacter, character = context.trigger.character }
7876
or { kind = vim.lsp.protocol.CompletionTriggerKind.Invoked }
7977

8078
return source:get_completions(source_context):catch(function(err)

lua/blink/cmp/sources/lib/source.lua

+1-4
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ local async = require('blink.cmp.sources.lib.async')
33
local source = {}
44

55
--- @param config blink.cmp.SourceProviderConfig
6-
--- @return blink.cmp.SourceProvider
76
function source.new(config)
87
local self = setmetatable({}, { __index = source })
98
self.name = config[1]
@@ -22,18 +21,16 @@ function source:get_trigger_characters()
2221
return self.module:get_trigger_characters()
2322
end
2423

25-
--- @param context blink.cmp.CompletionContext
24+
--- @param context blink.cmp.Context
2625
--- @return blink.cmp.Task
2726
function source:get_completions(context)
2827
-- Return the previous successful completions if the context is the same
2928
-- and the data doesn't need to be updated
3029
if self.last_response ~= nil and self.last_response.context.id == context.id then
3130
if utils.should_run_request(context, self.last_response) == false then
32-
-- vim.print(self.name .. ': returning cached completions')
3331
return async.task.new(function(resolve) resolve(self.last_response) end)
3432
end
3533
end
36-
-- vim.print(self.name .. ': running completions request')
3734

3835
return async.task
3936
.new(function(resolve) return self.module:get_completions(context, resolve) end)

lua/blink/cmp/sources/lib/types.lua

+1-16
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@
22
--- @field kind number
33
--- @field character string | nil
44
---
5-
--- @class blink.cmp.CompletionContext : blink.cmp.TriggerContext
6-
--- @field trigger blink.cmp.CompletionTriggerContext | nil
7-
---
85
--- @class blink.cmp.CompletionResponse
96
--- @field is_incomplete_forward boolean
107
--- @field is_incomplete_backward boolean
@@ -14,19 +11,7 @@
1411
--- @class blink.cmp.Source
1512
--- @field new fun(opts: table): blink.cmp.Source
1613
--- @field get_trigger_characters (fun(self: blink.cmp.Source): string[]) | nil
17-
--- @field get_completions fun(self: blink.cmp.Source, context: blink.cmp.CompletionContext, callback: fun(response: blink.cmp.CompletionResponse)): (fun(): nil) | nil
14+
--- @field get_completions fun(self: blink.cmp.Source, context: blink.cmp.Context, callback: fun(response: blink.cmp.CompletionResponse)): (fun(): nil) | nil
1815
--- @field filter_completions (fun(self: blink.cmp.Source, response: blink.cmp.CompletionResponse): blink.cmp.CompletionItem[]) | nil
1916
--- @field should_show_completions (fun(self: blink.cmp.Source, response: blink.cmp.CompletionResponse): boolean) | nil
2017
--- @field resolve (fun(self: blink.cmp.Source, item: blink.cmp.CompletionItem, callback: fun(resolved_item: lsp.CompletionItem | nil)): ((fun(): nil) | nil)) | nil
21-
---
22-
--- @class blink.cmp.SourceProvider
23-
--- @field module blink.cmp.Source
24-
--- @field config blink.cmp.SourceProviderConfig
25-
--- @field last_context blink.cmp.CompletionContext | nil
26-
--- @field last_response blink.cmp.CompletionResponse | nil
27-
--- @field new fun(config: blink.cmp.SourceProviderConfig): blink.cmp.SourceProvider
28-
--- @field get_trigger_characters (fun(self: blink.cmp.Source): string[]) | nil
29-
--- @field get_completions fun(self: blink.cmp.Source, context: blink.cmp.CompletionContext): blink.cmp.Task
30-
--- @field filter_completions (fun(self: blink.cmp.Source, context: blink.cmp.CompletionContext, source_responses: table<string, blink.cmp.CompletionResponse>): blink.cmp.CompletionItem[]) | nil
31-
--- @field should_show_completions (fun(self: blink.cmp.Source, context: blink.cmp.CompletionContext, source_responses: table<string, blink.cmp.CompletionResponse>): boolean) | nil
32-
--- @field resolve fun(self: blink.cmp.Source, item: blink.cmp.CompletionItem, callback: fun(resolved_item: lsp.CompletionItem | nil)): blink.cmp.Task

lua/blink/cmp/sources/lib/utils.lua

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ local utils = {}
1111
function utils.should_run_request(new_context, response)
1212
local old_context = response.context
1313
-- get the text for the current and queued context
14-
local context_query = old_context.bounds.line:sub(old_context.bounds.start_col, old_context.bounds.end_col)
15-
local queued_context_query = new_context.bounds.line:sub(new_context.bounds.start_col, new_context.bounds.end_col)
14+
local context_query = old_context.line:sub(old_context.bounds.start_col, old_context.bounds.end_col)
15+
local queued_context_query = new_context.line:sub(new_context.bounds.start_col, new_context.bounds.end_col)
1616

1717
-- check if the texts are overlapping
1818
local is_before = vim.startswith(context_query, queued_context_query)

lua/blink/cmp/sources/lsp.lua

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ function lsp:get_completions(context, callback)
7373
local trigger_characters = self:get_trigger_characters()
7474
local trigger_character_block_list = { ' ', '\n', '\t' }
7575
local bounds = context.bounds
76-
local trigger_character_before_context = bounds.line:sub(bounds.start_col - 1, bounds.start_col - 1)
76+
local trigger_character_before_context = context.line:sub(bounds.start_col - 1, bounds.start_col - 1)
7777
if
7878
vim.tbl_contains(trigger_characters, trigger_character_before_context)
7979
and not vim.tbl_contains(trigger_character_block_list, trigger_character_before_context)

lua/blink/cmp/trigger.lua

+28-34
Original file line numberDiff line numberDiff line change
@@ -8,29 +8,28 @@
88
--- @field start_col number
99
--- @field end_col number
1010
---
11-
--- @class blink.cmp.TriggerContext
11+
--- @class blink.cmp.Context
1212
--- @field id number
1313
--- @field bounds blink.cmp.TriggerBounds
14+
--- @field bufnr number
1415
--- @field treesitter_node table | nil
15-
---
16-
--- @class blink.cmp.ShowContext : blink.cmp.TriggerContext
17-
--- @field trigger_character string | nil
16+
--- @field trigger { kind: number, character: string | nil }
1817
---
1918
--- @class blink.cmp.TriggerEventTargets
20-
--- @field on_show fun(context: blink.cmp.ShowContext)
19+
--- @field on_show fun(context: blink.cmp.Context)
2120
--- @field on_hide fun()
2221
---
2322
--- @class blink.cmp.Trigger
24-
--- @field context blink.cmp.TriggerContext | nil
25-
--- @field context_last_id number
23+
--- @field context blink.cmp.Context | nil
24+
--- @field current_context_id number
2625
--- @field context_regex string
2726
--- @field event_targets blink.cmp.TriggerEventTargets
2827

2928
local sources = require('blink.cmp.sources.lib')
3029

3130
--- @class blink.cmp.Trigger
3231
local trigger = {
33-
context_last_id = -1,
32+
current_context_id = -1,
3433
context = nil,
3534
context_regex = '[%w_\\-]',
3635

@@ -108,15 +107,23 @@ end
108107
function trigger.show(opts)
109108
opts = opts or {}
110109

111-
-- update context (to update bounds and treesitter node)
112-
-- todo: this behavior isn't obvious
113-
trigger.context = trigger.get_context()
114-
115-
trigger.event_targets.on_show({
116-
id = trigger.context.id,
117-
bounds = trigger.context.bounds,
118-
trigger_character = opts.trigger_character,
119-
})
110+
-- update context
111+
local cursor = vim.api.nvim_win_get_cursor(0)
112+
if trigger.context == nil then trigger.current_context_id = trigger.current_context_id + 1 end
113+
trigger.context = {
114+
id = trigger.current_context_id,
115+
bufnr = vim.api.nvim_get_current_buf(),
116+
cursor = cursor,
117+
line = vim.api.nvim_buf_get_lines(0, cursor[1] - 1, cursor[1], false)[1],
118+
bounds = helpers.get_context_bounds(trigger.context_regex),
119+
trigger = {
120+
kind = opts.trigger_character and vim.lsp.protocol.CompletionTriggerKind.TriggerCharacter
121+
or vim.lsp.protocol.CompletionTriggerKind.Invoked,
122+
character = opts.trigger_character,
123+
},
124+
}
125+
126+
trigger.event_targets.on_show(trigger.context)
120127
end
121128

122129
function trigger.listen_on_show(callback) trigger.event_targets.on_show = callback end
@@ -130,19 +137,7 @@ end
130137

131138
function trigger.listen_on_hide(callback) trigger.event_targets.on_hide = callback end
132139

133-
------ Context ------
134-
-- Gets the current context, always updating the bounds to the current position
135-
--- @return blink.cmp.TriggerContext
136-
function trigger.get_context()
137-
local bounds = helpers.get_query(trigger.context_regex)
138-
-- local treesitter_node = helpers.get_treesitter_node_at_cursor()
139-
if not trigger.context then
140-
trigger.context_last_id = trigger.context_last_id + 1
141-
trigger.context = { id = trigger.context_last_id, bounds = bounds }
142-
end
143-
return { id = trigger.context.id, bounds = bounds }
144-
end
145-
140+
--- @param context blink.cmp.ShowContext | nil
146141
--- @param cursor number[]
147142
--- @return boolean
148143
function trigger.within_query_bounds(cursor)
@@ -163,12 +158,11 @@ end
163158
-- Moves forward and backwards around the cursor looking for word boundaries
164159
--- @param regex string
165160
--- @return blink.cmp.TriggerBounds
166-
function helpers.get_query(regex)
167-
local bufnr = vim.api.nvim_get_current_buf()
161+
function helpers.get_context_bounds(regex)
168162
local cursor_line = vim.api.nvim_win_get_cursor(0)[1]
169163
local cursor_col = vim.api.nvim_win_get_cursor(0)[2]
170164

171-
local line = vim.api.nvim_buf_get_lines(bufnr, cursor_line - 1, cursor_line, false)[1]
165+
local line = vim.api.nvim_buf_get_lines(0, cursor_line - 1, cursor_line, false)[1]
172166
local start_col = cursor_col
173167
while start_col > 1 do
174168
local char = line:sub(start_col, start_col)
@@ -186,7 +180,7 @@ function helpers.get_query(regex)
186180
end_col = end_col + 1
187181
end
188182

189-
return { line = line, line_number = cursor_line, start_col = start_col, end_col = end_col }
183+
return { line_number = cursor_line, start_col = start_col, end_col = end_col }
190184
end
191185

192186
--- @return TSNode | nil

0 commit comments

Comments
 (0)