perf(picker): cache wether ts lang exists and disable smooth scrolling on big files

This commit is contained in:
Folke Lemaitre 2025-02-05 21:39:31 +01:00
parent c1e86b0686
commit 719b36fa70
No known key found for this signature in database
GPG key ID: 41F8B1FBACAE2040
4 changed files with 41 additions and 8 deletions

View file

@ -78,7 +78,7 @@ function M.new(picker)
vim.schedule(function()
input.picker:find({ refresh = false })
end)
end, { ms = picker.opts.live and 100 or 30 }),
end, { ms = picker.opts.live and 200 or 30 }),
{ buf = true }
)
return self

View file

@ -499,7 +499,7 @@ M._throttled_preview = M._show_preview
-- otherwise throttle the preview.
function M:show_preview()
if not self.preview.item then
self:_show_preview()
return self:_show_preview()
end
return self:_throttled_preview()
end

View file

@ -10,6 +10,7 @@
---@field winhl string
---@field title? string
---@field split_layout? boolean
---@field opts? snacks.picker.previewers.Config
local M = {}
M.__index = M
@ -28,6 +29,7 @@ local ns_loc = vim.api.nvim_create_namespace("snacks.picker.preview.loc")
---@param main? number
function M.new(opts, main)
local self = setmetatable({}, M)
self.opts = opts.previewers
self.winhl = Snacks.picker.highlight.winhl("SnacksPickerPreview", { CursorLine = "Visual" })
local win_opts = Snacks.win.resolve(
{
@ -237,11 +239,10 @@ function M:highlight(opts)
filename = opts.file,
})
end
local lang = opts.lang or ft and vim.treesitter.language.get_lang(ft)
if not (lang and pcall(vim.treesitter.start, self.win.buf, lang)) then
if ft then
vim.bo[self.win.buf].syntax = ft
end
self:check_big()
local lang = Snacks.picker.highlight.get_lang({ lang = opts.lang, ft = ft })
if not (lang and pcall(vim.treesitter.start, self.win.buf, lang)) and ft then
vim.bo[self.win.buf].syntax = ft
end
end
@ -312,6 +313,23 @@ function M:loc()
end
end
function M:check_big()
local big = self:is_big()
vim.b[self.win.buf].snacks_scroll = not big
end
function M:is_big()
local lines = vim.api.nvim_buf_line_count(self.win.buf)
if lines > 1000 then
return true
end
local path = self.item and self.item.file and Snacks.picker.util.path(self.item)
if path and vim.fn.getfsize(path) > 1.5 * 1024 * 1024 then
return true
end
return false
end
---@param lines string[]
function M:set_lines(lines)
vim.bo[self.win.buf].modifiable = true

View file

@ -1,6 +1,21 @@
---@class snacks.picker.highlight
local M = {}
M.langs = {} ---@type table<string, boolean>
---@param opts? {lang?:string, ft?:string}
function M.get_lang(opts)
opts = opts or {}
local lang = opts.lang or (opts.ft and vim.treesitter.language.get_lang(opts.ft)) or nil
if not lang then
return
end
if M.langs[lang] == nil then
M.langs[lang] = pcall(vim.treesitter.language.add, lang)
end
return M.langs[lang] and lang or nil
end
---@param opts? {buf?:number, code?:string, ft?:string, lang?:string, file?:string, extmarks?:boolean}
function M.get_highlights(opts)
opts = opts or {}
@ -13,7 +28,7 @@ function M.get_highlights(opts)
or (opts.buf and vim.bo[opts.buf].filetype)
or (opts.file and vim.filetype.match({ filename = opts.file, buf = 0 }))
or vim.bo.filetype
local lang = opts.lang or vim.treesitter.language.get_lang(ft)
local lang = M.get_lang({ lang = opts.lang, ft = ft })
local parser ---@type vim.treesitter.LanguageTree?
if lang then
local ok = false