Skip to content
This repository was archived by the owner on Oct 13, 2021. It is now read-only.

Commit ec41ef7

Browse files
committed
feat: context aware completion
fix some stuff
1 parent 22e46d3 commit ec41ef7

File tree

5 files changed

+42
-28
lines changed

5 files changed

+42
-28
lines changed

lua/completion/complete.lua

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ M.clearCache = function()
3131
end
3232

3333
-- perform completion
34-
M.performComplete = function(complete_source, complete_items_map, manager, bufnr, prefix, textMatch)
34+
M.performComplete = function(complete_source, complete_items_map, manager, opt)
3535

3636
manager.insertChar = false
3737
if vim.fn.has_key(complete_source, "mode") > 0 then
@@ -50,7 +50,7 @@ M.performComplete = function(complete_source, complete_items_map, manager, bufnr
5050
table.insert(callback_array, true)
5151
else
5252
table.insert(callback_array, complete_items.callback)
53-
complete_items.trigger(prefix, textMatch, bufnr, manager)
53+
complete_items.trigger(manager, opt)
5454
end
5555
table.insert(items_array, complete_items.item)
5656
end
@@ -65,14 +65,14 @@ M.performComplete = function(complete_source, complete_items_map, manager, bufnr
6565
-- only perform complete when callback_array are all true
6666
if checkCallback(callback_array) == true and timer:is_closing() == false then
6767
if api.nvim_get_mode()['mode'] == 'i' or api.nvim_get_mode()['mode'] == 'ic' then
68-
local items = getCompletionItems(items_array, prefix)
68+
local items = getCompletionItems(items_array, opt.prefix)
6969
if vim.g.completion_sorting ~= "none" then
7070
util.sort_completion_items(items)
7171
end
7272
if #items ~= 0 then
7373
-- reset insertChar and handle auto changing source
7474
cache_complete_items = items
75-
vim.fn.complete(textMatch+1, items)
75+
vim.fn.complete(opt.textMatch+1, items)
7676
manager.changeSource = false
7777
else
7878
manager.changeSource = true
@@ -86,15 +86,15 @@ M.performComplete = function(complete_source, complete_items_map, manager, bufnr
8686
if api.nvim_get_mode()['mode'] == 'i' or api.nvim_get_mode()['mode'] == 'ic' then
8787
local items = {}
8888
for _, item in ipairs(cache_complete_items) do
89-
match.matching(items, prefix, item)
89+
match.matching(items, opt.prefix, item)
9090
end
9191
if vim.g.completion_sorting ~= "none" then
9292
util.sort_completion_items(items)
9393
end
9494
if #items ~= 0 then
9595
-- reset insertChar and handle auto changing source
9696
cache_complete_items = items
97-
vim.fn.complete(textMatch+1, items)
97+
vim.fn.complete(opt.textMatch+1, items)
9898
manager.changeSource = false
9999
else
100100
cache_complete_items = {}

lua/completion/matching.lua

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ M.matching = function(complete_items, prefix, item)
5252
for _, method in ipairs(matcher_list) do
5353
local is_match, score = matching_strategy[method](prefix, item.word)
5454
if is_match then
55+
if item.abbr == nil then
56+
item.abbr = item.word
57+
end
5558
item.score = score
5659
if item.priority ~= nil then
5760
item.priority = item.priority + 10*matching_priority

lua/completion/source.lua

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ local getTriggerCharacter = function()
6060
return triggerCharacter
6161
end
6262

63-
local triggerCurrentCompletion = function(manager, bufnr, line_to_cursor, prefix, textMatch, force)
63+
local triggerCurrentCompletion = function(manager, bufnr, line_to_cursor, prefix, textMatch, suffix, force)
6464
-- avoid rebundant calling of completion
6565
if manager.insertChar == false then return end
6666

@@ -111,15 +111,16 @@ local triggerCurrentCompletion = function(manager, bufnr, line_to_cursor, prefix
111111
M.chain_complete_index = 1
112112
end
113113

114-
complete.performComplete(complete_source, complete_items_map, manager, bufnr, prefix, textMatch)
114+
complete.performComplete(complete_source, complete_items_map, manager, {bufnr=bufnr, prefix=prefix, textMatch=textMatch, suffix=suffix, line_to_cursor=line_to_cursor})
115115
end
116116

117117
local getPositionParam = function()
118118
local bufnr = api.nvim_get_current_buf()
119119
local pos = api.nvim_win_get_cursor(0)
120120
local line = api.nvim_get_current_line()
121121
local line_to_cursor = line:sub(1, pos[2])
122-
return bufnr, line_to_cursor
122+
local cursor_to_end = line:sub(pos[2]+1, #line)
123+
return bufnr, line_to_cursor, cursor_to_end
123124
end
124125

125126
------------------------------------------------------------------------
@@ -132,19 +133,23 @@ function M.triggerCompletion(force, manager)
132133
if force then
133134
M.chain_complete_index = 1
134135
end
135-
local bufnr, line_to_cursor = getPositionParam()
136+
local bufnr, line_to_cursor, cursor_to_end = getPositionParam()
136137
local textMatch = vim.fn.match(line_to_cursor, '\\k*$')
137138
local prefix = line_to_cursor:sub(textMatch+1)
139+
local rev_textMatch = #cursor_to_end - vim.fn.match(cursor_to_end:reverse(), '\\k*$')
140+
local suffix = cursor_to_end:sub(1, rev_textMatch)
138141
manager.insertChar = true
139142
-- force is used when manually trigger, so it doesn't repect the trigger word length
140-
triggerCurrentCompletion(manager, bufnr, line_to_cursor, prefix, textMatch, force)
143+
triggerCurrentCompletion(manager, bufnr, line_to_cursor, prefix, textMatch, suffix, force)
141144
end
142145

143146
-- Handler for auto completion
144147
function M.autoCompletion(manager)
145-
local bufnr, line_to_cursor = getPositionParam()
148+
local bufnr, line_to_cursor, cursor_to_end = getPositionParam()
146149
local textMatch = vim.fn.match(line_to_cursor, '\\k*$')
147150
local prefix = line_to_cursor:sub(textMatch+1)
151+
local rev_textMatch = #cursor_to_end - vim.fn.match(cursor_to_end:reverse(), '\\k*$')
152+
local suffix = cursor_to_end:sub(1, rev_textMatch)
148153
local length = vim.g.completion_trigger_keyword_length
149154

150155
-- reset completion when deleting character in insert mode
@@ -171,7 +176,7 @@ function M.autoCompletion(manager)
171176
-- stop auto completion when all sources return no complete-items
172177
if M.stop_complete == true then return end
173178

174-
triggerCurrentCompletion(manager, bufnr, line_to_cursor, prefix, textMatch)
179+
triggerCurrentCompletion(manager, bufnr, line_to_cursor, prefix, textMatch, suffix)
175180

176181
end
177182

lua/completion/source/lsp.lua

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ M.getCompletionItems = function(_, _)
1010
return M.items
1111
end
1212

13-
local function get_completion_word(item, prefix)
13+
local function get_completion_word(item, prefix, suffix)
1414
if item.textEdit ~= nil and item.textEdit ~= vim.NIL
1515
and item.textEdit.newText ~= nil and (item.insertTextFormat ~= 2 or vim.fn.exists('g:loaded_vsnip_integ')) then
1616
local start_range = item.textEdit.range["start"]
@@ -36,7 +36,7 @@ local function get_completion_word(item, prefix)
3636
return item.label
3737
end
3838

39-
local function text_document_completion_list_to_complete_items(result, prefix)
39+
local function text_document_completion_list_to_complete_items(result, opt)
4040
local items = vim.lsp.util.extract_completion_items(result)
4141
if vim.tbl_isempty(items) then
4242
return {}
@@ -63,19 +63,28 @@ local function text_document_completion_list_to_complete_items(result, prefix)
6363
end
6464
item.info = info
6565

66-
item.word = get_completion_word(completion_item, prefix)
66+
item.word = get_completion_word(completion_item, opt.prefix, opt.suffix)
67+
if opt.suffix ~= nil and #opt.suffix ~= 0 then
68+
local index = item.word:find(opt.suffix)
69+
if index ~= nil then
70+
local newWord = item.word
71+
newWord = newWord:sub(1, index-1)
72+
item.word = newWord
73+
print(item.word, index, newWord)
74+
end
75+
end
6776
item.user_data = {
6877
lsp = {
69-
completion_item = completion_item
78+
completion_item = completion_item,
7079
}
7180
}
7281
local kind = protocol.CompletionItemKind[completion_item.kind]
7382
item.kind = customize_label[kind] or kind
7483
item.abbr = completion_item.label
84+
-- get_context_aware_snippets(item, completion_item, opt.textMatch)
7585
item.priority = vim.g.completion_items_priority[item.kind]
7686
item.menu = completion_item.detail or ''
77-
78-
match.matching(matches, prefix, item)
87+
match.matching(matches, opt.prefix, item)
7988
end
8089
end
8190

@@ -86,20 +95,20 @@ M.getCallback = function()
8695
return M.callback
8796
end
8897

89-
M.triggerFunction = function(prefix, _, bufnr, _)
98+
M.triggerFunction = function(manager, opt)
9099
local params = vim.lsp.util.make_position_params()
91100
M.callback = false
92101
M.items = {}
93102
if #vim.lsp.buf_get_clients() == 0 then
94103
M.callback = true
95104
return
96105
end
97-
vim.lsp.buf_request(bufnr, 'textDocument/completion', params, function(err, _, result)
106+
vim.lsp.buf_request(opt.bufnr, 'textDocument/completion', params, function(err, _, result)
98107
if err or not result then
99108
M.callback = true
100109
return
101110
end
102-
local matches = text_document_completion_list_to_complete_items(result, prefix)
111+
local matches = text_document_completion_list_to_complete_items(result, opt)
103112
M.items = matches
104113
M.callback = true
105114
end)

lua/completion/source/path.lua

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,17 +57,14 @@ M.getCallback = function()
5757
return M.callback
5858
end
5959

60-
M.triggerFunction = function()
61-
local pos = api.nvim_win_get_cursor(0)
62-
local line = api.nvim_get_current_line()
63-
local line_to_cursor = line:sub(1, pos[2])
60+
M.triggerFunction = function(_, opt)
6461
local keyword
6562
if vim.v.completed_item ~= nil and vim.v.completed_item.kind == 'Path' and
66-
line_to_cursor:find(vim.v.completed_item.word) then
63+
opt.line_to_cursor:find(vim.v.completed_item.word) then
6764
keyword = M.keyword..vim.v.completed_item.word..'/'
6865
else
6966
M.keyword = nil
70-
keyword = line_to_cursor:match("[^%s\"\']+%S*/?$")
67+
keyword = opt.line_to_cursor:match("[^%s\"\']+%S*/?$")
7168
end
7269

7370
if keyword ~= nil and keyword ~= '/' then

0 commit comments

Comments
 (0)