tpope / vim-fireplace

fireplace.vim: Clojure REPL support
https://www.vim.org/scripts/script.php?script_id=4978
1.75k stars 139 forks source link

Use faster get_complete_context in nvim-0.5 #390

Open SevereOverfl0w opened 2 years ago

SevereOverfl0w commented 2 years ago

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.

I've benchmarked before & after using the clip library and get_complete_context goes from 6.244431 to 0.027365 self time (I will include the profile in a comment, as I cannot upload a file to a PR).

I've implemented this such that existing vim users will experience no degradation, that's required gymnastics in defining s:get_complete_context. To keep s:get_complete_context very fast, I've avoided conditionals which won't change while vim is running.

SevereOverfl0w commented 2 years ago

profile.zip

Apparently I could, but for some reason there's no upload button! Uploaded here anyway.

The benchmark script I used was:

34
normal! o

for s:item in split(';; sjdkfj kfjksdjfk jksdfjksdjf djksfjksdjfksjdf jsdkfjskdfjksd jfksdjf ksdjfksdjf sdjfksd fksjdfk jdsfkjd', '\zs')
    call feedkeys('a' . s:item . "\<C-x>\<C-o>", 'tx')
    sleep 50m
endfor

And to run it I opened vim and did:

profile start /tmp/filename
profile func *complete*
source benchmark.vim
profile stop

The function I tested this within is 54 lines in total, within a file that is 346 lines long. I originally noticed this problem in a file that was ~500 lines long when editing a function of around ~100 lines towards the end of the file.

tpope commented 2 years ago

First question: Why autoload/_fireplace.lua/require'_fireplace'? Is this a convention?

SevereOverfl0w commented 2 years ago

There's no way to mark code "private" in lua, _ is a convention for that (similar to python).

tpope commented 2 years ago

That answers half the question. Why autoload/? It's not autoloaded. And Neovim seems to prefer lua/.

SevereOverfl0w commented 2 years ago

@tpope It is in lua, I assumed you typo'd autoload. Apologies.

tpope commented 2 years ago

My bad, could have sworn I saw autoload/_fireplace.lua in the diff.

If the function changes, how do I reload it? I think ideally, reloading autoload/fireplace.vim would also reload the lua file.

Can we go ahead and structure this in a way that isn't limited to a single function?

SevereOverfl0w commented 2 years ago

I can make that change, no problem!

https://github.com/nanotee/nvim-lua-guide has tips for developing against nvim + lua. https://github.com/nanotee/nvim-lua-guide#reloading-cached-modules explains reloading. I was just restarting nvim personally, it's fast!

SevereOverfl0w commented 2 years ago

I've made that change. I've also fixed a bug I noticed where if you started a new form the treesitter AST needs to be updated. I've re-run the benchmark, and the numbers are approximately the same.