-
Notifications
You must be signed in to change notification settings - Fork 130
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
Use a scratch buffer with syntax highlighting only for previews #467
Conversation
What is the purpose of a scratch-based preview instead of loading the buffer itself? |
It's an attempt of fixing this #435, but also speeding up previews in general by not having the LSP run on them as usually people just cycle through files quickly (at least it's usually what I do when enabling previews). It seems that other previewers on other popular plugins operate this way. |
Hmmm...that linked bug seems like something that should be fixed upstream. If an async process is trying to access an invalid buffer, it needs to check if the buffer is valid before operating. The performance increase is interesting, but how much of a boost is it? Is it just tied to not attaching the LSP client? This is a decently-sized chunk of code and complexity, so I just want to make sure that the benefit is worth the cost. If the goal is just to avoid attaching the LSP, could we instead do something simpler like suppress the FileType autocmd and manually trigger treesitter highlighting? |
Sorry for getting back to you promptly on this, it really depends on the kind of LSP you are running, when I have the Unreal codebase open with clangd running, browsing CPP files makes at least one of my CPU spike. Browsing my lua config seems ok, on rust it depends. The thing is I don't really nead LSP on preview of files, I know the bug is on neovim side and it's still gonna happen if you enable the LSP on previews, for me it just pointed out that the LSP is not needed, I rather that it has minimal impact on my CPU. But I agree that I should try to make a leaner implementation, the code above has been heavily inspired by previews in popular plugins thus the complexity. |
I tested this branch and I really like it. I'll use it until upstream fixes semantic tokens or this PR will be merged. |
I'm having this same issue. Is there any hope at getting this into the master branch? I'm going to try the scratch-preview branch for now as well, but it would be nice to have a long-term solution. |
FYI - I tried the scratch-preview branch from @jelmansouri. It is an improvement. The error still happens, just much more infrequently. |
Strike that last comment. It's been a long day :) I must have forgot to restart neovim because now the branch is working with no issues. |
I agree with you completely. In fact, this is the primary reason I prefer mini.files over oil—much better handling of previews. Mini is so much faster in this regard. It also skips previews of binary files. But I really prefer how oil uses the current window when opened for the reasons stated in the famous oil and vinegar blog post. Unfortunately the previews in oil are too heavyweight—especially on large files. I’m interested to see how this work progresses in this PR. Will give a try this weekend. [edit]: I just noticed #511 was opened yesterday to disable previews on large files. I don't think that is the right approach to take because mini.files handles large previews instantaneously because it only reads the number of lines needed to fill the preview buffer. The solution in #511 is really a workaround for the bigger issue of preview handling in oil. |
In addition to eliminating LSP, to better handle large files, I modified @jelmansouri's M.read_file_to_scratch_buffer = function(path, opts)
local bufnr = vim.api.nvim_create_buf(false, true)
vim.bo[bufnr].bufhidden = "wipe"
vim.bo[bufnr].buftype = "nofile"
vim.b[bufnr].oil_preview_buffer = true
-- Next two lines lifted from mini.files
local has_lines, read_res = pcall(vim.fn.readfile, path, "", vim.o.lines)
local lines = has_lines and vim.split(table.concat(read_res, "\n"), "\n") or {}
if not vim.api.nvim_buf_is_valid(bufnr) then
return
end
local ok = pcall(vim.api.nvim_buf_set_lines, bufnr, 0, -1, false, lines)
if not ok then
return
end
local ft = vim.filetype.match({ filename = path })
if ft and ft ~= "" then
local lang = vim.treesitter.language.get_lang(ft)
if not pcall(vim.treesitter.start, bufnr, lang) then
vim.bo[bufnr].syntax = ft
end
end
return bufnr
end I would love to see oil adopt something like this for better performance of previews—eliminating LSP and reading only a portion of the file. |
@jelmansouri One thing I noticed with the PR is that directory previews are not always updated. Do you notice the same on your side? |
60fe230
to
3f01a15
Compare
Yes, I Updated to latest and integrated your change, I'll iterate a bit more on it to clean it up. |
80fb1e0
to
22f48aa
Compare
@pkazmier Compared to the original code where reading and opening the file was asynchronous, now it is sync. I decided to leave your code to address the complexity concern raised by @stevearc. |
@pkazmier you need to add this now to enable the behaviour in oil setup preview_win = {
scratch_buffer = true,
limit_scratch_buffer = true,
}, |
I was pulling my hairs out on this issue, I thought I messed something up in my lsp config, but seems not to be the case. |
To be fair the issue itself needs to be fixed within neovim, this is more another take on previews which make them lighter weight (similar to how other plugins operate) |
Thanks all for the hard work iterating on this PR! I did a pass on refactoring some of the logic and behavior:
LMK if these changes work for you |
All makes sense, thank you so much for this. |
Thanks for the collaboration, everyone! I think this ended up in a good place. |
Thank you guys so much for you work on this. Oil.nvim is by far the best vim file browser. It's great to see it's maintained well. |
I think the next area of optimization could be dealing with large directories. With mini.files, I can move my cursor up and down with no delay at all even when one of the middle items is a directory with 10,000 files in it. Today, with oil and preview window open, there is a noticeable lag on the order of seconds doing the same. Not sure how to go about that one though. |
@pkazmier I recently made a series of commits designed to improve performance on large directories. Out of the box it should now be quite fast, but there are some view options that will slow it down significantly when enabled ( If you're curious about how I've been benchmarking or profiling oil, check out the 3 Makefile targets I added recently:
|
The issue is due to the vim.opt.foldmethod = "expr"
vim.opt.foldexpr = "v:lua.vim.treesitter.foldexpr()" This same issue was reported in mini.files as well due to an upstream neovim bug. Ultimately, the author resolved by explicitly setting Fortunately, oil has win_options = {
foldenable = false,
foldmethod = "manual",
}, |
See discussion here: stevearc/oil.nvim#467 (comment)
Thanks for fixing @stevearc! I saw the commit you made to address the above. |
because [#467](stevearc/oil.nvim#467) fixed the LSP issue in previewing
This is a proof of concept based on telescope and trouble implementation for previews. I can work further on the PR to make it worthy of pushing if the maintainer is ok with this.