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() vim.schedule(function()
input.picker:find({ refresh = false }) input.picker:find({ refresh = false })
end) end)
end, { ms = picker.opts.live and 100 or 30 }), end, { ms = picker.opts.live and 200 or 30 }),
{ buf = true } { buf = true }
) )
return self return self

View file

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

View file

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

View file

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