Skip to content

Commit 0c817aa

Browse files
Use faster get_complete_context in nvim-0.5
For users using an "autocomplete" package of some kind (so completion on every key press), a slow completion function adds noticeable lag to typing. The use of searchpairpos really slows down the current context implementation. Since nvim-0.5, there's a treesitter package included. Treesitter can incrementally parse the tree, and offers a very fast way to find the root node.
1 parent c9a155b commit 0c817aa

File tree

2 files changed

+52
-1
lines changed

2 files changed

+52
-1
lines changed

autoload/fireplace.vim

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ function! s:candidate(val) abort
192192
\ }
193193
endfunction
194194

195-
function! s:get_complete_context() abort
195+
function! s:internal_get_complete_context() abort
196196
" Find toplevel form
197197
" If cursor is on start parenthesis we don't want to find the form
198198
" If cursor is on end parenthesis we want to find the form
@@ -223,6 +223,14 @@ function! s:get_complete_context() abort
223223
return strpart(expr, 0, p) . ' __prefix__ ' . strpart(expr, p)
224224
endfunction
225225

226+
if has('nvim-0.5')
227+
let s:lua_impl = luaeval("require'_fireplace'")
228+
else
229+
let s:lua_impl = {}
230+
endif
231+
232+
let s:get_complete_context = get(s:lua_impl, 'get_completion_context', function('s:internal_get_complete_context'))
233+
226234
function! s:complete_extract(msg) abort
227235
let trans = '{"word": (v:val =~# ''[./]'' ? "" : matchstr(a:base, ''^.\+/'')) . v:val}'
228236
let value = get(a:msg, 'value', get(a:msg, 'completions'))

lua/_fireplace.lua

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
local fireplace_impl = {[vim.type_idx] = vim.types.dictionary}
2+
3+
if vim.treesitter then
4+
local has_ts, ts = pcall(require, 'nvim-treesitter.ts_utils')
5+
6+
if has_ts and vim.treesitter.language.add('clojure') then
7+
fireplace_impl['get_completion_context'] = function()
8+
vim.treesitter.get_parser(0, 'clojure'):parse()
9+
local node = ts.get_node_at_cursor()
10+
local one_ago = nil
11+
local two_ago = nil
12+
13+
while(node ~= nil) do
14+
two_ago = one_ago
15+
one_ago = node
16+
node = node:parent()
17+
end
18+
19+
local root_node = two_ago or one_ago or node
20+
21+
if root_node ~= nil then
22+
local strs = ts.get_node_text(root_node)
23+
local nrow1, ncol1, nline2, ncol2 = root_node:range()
24+
local crow, ccol = unpack(vim.api.nvim_win_get_cursor(0))
25+
26+
local idx = crow - nrow1
27+
local line = strs[idx]
28+
local coloffset = 0
29+
if crow == nrow1 then
30+
coloffset = ncol1
31+
end
32+
33+
strs[idx] = string.sub(line, 1 + coloffset, ccol + coloffset) .. ' __prefix__ ' .. string.sub(line, ccol+coloffset+1, -1)
34+
35+
return table.concat(strs, "\n")
36+
else
37+
return ""
38+
end
39+
end
40+
end
41+
end
42+
43+
return fireplace_impl

0 commit comments

Comments
 (0)