mirror of
https://github.com/folke/snacks.nvim
synced 2025-08-05 11:18:26 +00:00
perf(picker): small optims for abort
This commit is contained in:
parent
d283d9e182
commit
317a2093ea
7 changed files with 30 additions and 13 deletions
|
@ -5,7 +5,6 @@ local Async = require("snacks.picker.util.async")
|
||||||
---@field task snacks.picker.Async
|
---@field task snacks.picker.Async
|
||||||
---@field items snacks.picker.finder.Item[]
|
---@field items snacks.picker.finder.Item[]
|
||||||
---@field filter? snacks.picker.Filter
|
---@field filter? snacks.picker.Filter
|
||||||
---@field has_scores? boolean
|
|
||||||
local M = {}
|
local M = {}
|
||||||
M.__index = M
|
M.__index = M
|
||||||
|
|
||||||
|
@ -46,7 +45,6 @@ function M:run(picker)
|
||||||
local default_score = require("snacks.picker.core.matcher").DEFAULT_SCORE
|
local default_score = require("snacks.picker.core.matcher").DEFAULT_SCORE
|
||||||
self.task:abort()
|
self.task:abort()
|
||||||
self.items = {}
|
self.items = {}
|
||||||
self.has_scores = false
|
|
||||||
local yield ---@type fun()
|
local yield ---@type fun()
|
||||||
self.filter = picker.input.filter:clone({ trim = true })
|
self.filter = picker.input.filter:clone({ trim = true })
|
||||||
local finder = self._find(picker.opts, self.filter)
|
local finder = self._find(picker.opts, self.filter)
|
||||||
|
@ -56,7 +54,6 @@ function M:run(picker)
|
||||||
local function add(item)
|
local function add(item)
|
||||||
item.idx, item.score = #self.items + 1, default_score
|
item.idx, item.score = #self.items + 1, default_score
|
||||||
self.items[item.idx] = item
|
self.items[item.idx] = item
|
||||||
self.has_scores = self.has_scores or item.score_add ~= nil
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- PERF: if finder is a table, we can skip the async part
|
-- PERF: if finder is a table, we can skip the async part
|
||||||
|
@ -89,8 +86,10 @@ function M:run(picker)
|
||||||
end, async)
|
end, async)
|
||||||
end):on("done", function()
|
end):on("done", function()
|
||||||
collectgarbage("restart")
|
collectgarbage("restart")
|
||||||
picker.matcher.task:resume()
|
if not self.task:aborted() then
|
||||||
picker:update()
|
picker.matcher.task:resume()
|
||||||
|
picker:update()
|
||||||
|
end
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -470,10 +470,11 @@ function M:close()
|
||||||
end
|
end
|
||||||
self.layout:close()
|
self.layout:close()
|
||||||
self.updater:stop()
|
self.updater:stop()
|
||||||
|
self.finder:abort()
|
||||||
|
self.matcher:abort()
|
||||||
M._active[self] = nil
|
M._active[self] = nil
|
||||||
vim.schedule(function()
|
vim.schedule(function()
|
||||||
self.matcher:abort()
|
-- order matters!
|
||||||
self.finder:abort()
|
|
||||||
self.input:close()
|
self.input:close()
|
||||||
self.preview:close()
|
self.preview:close()
|
||||||
end)
|
end)
|
||||||
|
|
|
@ -108,7 +108,7 @@ function M.files(opts, filter)
|
||||||
return require("snacks.picker.source.proc").proc(vim.tbl_deep_extend("force", {
|
return require("snacks.picker.source.proc").proc(vim.tbl_deep_extend("force", {
|
||||||
cmd = cmd,
|
cmd = cmd,
|
||||||
args = args,
|
args = args,
|
||||||
notify = false,
|
notify = not opts.live,
|
||||||
---@param item snacks.picker.finder.Item
|
---@param item snacks.picker.finder.Item
|
||||||
transform = function(item)
|
transform = function(item)
|
||||||
item.cwd = cwd
|
item.cwd = cwd
|
||||||
|
|
|
@ -108,7 +108,7 @@ function M.grep(opts, filter)
|
||||||
local cwd = not absolute and vim.fs.normalize(opts and opts.cwd or uv.cwd() or ".") or nil
|
local cwd = not absolute and vim.fs.normalize(opts and opts.cwd or uv.cwd() or ".") or nil
|
||||||
local cmd, args = get_cmd(opts, filter)
|
local cmd, args = get_cmd(opts, filter)
|
||||||
return require("snacks.picker.source.proc").proc(vim.tbl_deep_extend("force", {
|
return require("snacks.picker.source.proc").proc(vim.tbl_deep_extend("force", {
|
||||||
notify = false,
|
notify = not opts.live,
|
||||||
cmd = cmd,
|
cmd = cmd,
|
||||||
args = args,
|
args = args,
|
||||||
---@param item snacks.picker.finder.Item
|
---@param item snacks.picker.finder.Item
|
||||||
|
|
|
@ -31,6 +31,7 @@ function M.proc(opts)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local aborted = false
|
local aborted = false
|
||||||
local stdout = assert(uv.new_pipe())
|
local stdout = assert(uv.new_pipe())
|
||||||
opts = vim.tbl_deep_extend("force", {}, opts or {}, {
|
opts = vim.tbl_deep_extend("force", {}, opts or {}, {
|
||||||
|
@ -44,7 +45,7 @@ function M.proc(opts)
|
||||||
if not aborted and code ~= 0 and opts.notify ~= false then
|
if not aborted and code ~= 0 and opts.notify ~= false then
|
||||||
local full = { opts.cmd or "" }
|
local full = { opts.cmd or "" }
|
||||||
vim.list_extend(full, opts.args or {})
|
vim.list_extend(full, opts.args or {})
|
||||||
return Snacks.notify.error(("Command failed:\n- cmd: `%s`"):format(table.concat(full, " ")))
|
Snacks.notify.error(("Command failed:\n- cmd: `%s`"):format(table.concat(full, " ")))
|
||||||
end
|
end
|
||||||
stdout:close()
|
stdout:close()
|
||||||
handle:close()
|
handle:close()
|
||||||
|
@ -55,9 +56,12 @@ function M.proc(opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
local prev ---@type string?
|
local prev ---@type string?
|
||||||
|
local queue = require("snacks.picker.util.queue").new()
|
||||||
|
|
||||||
self:on("abort", function()
|
self:on("abort", function()
|
||||||
aborted = true
|
aborted = true
|
||||||
|
queue:clear()
|
||||||
|
cb = function() end
|
||||||
if not handle:is_closing() then
|
if not handle:is_closing() then
|
||||||
handle:kill("sigterm")
|
handle:kill("sigterm")
|
||||||
vim.defer_fn(function()
|
vim.defer_fn(function()
|
||||||
|
@ -97,9 +101,10 @@ function M.proc(opts)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local queue = require("snacks.picker.util.queue").new()
|
|
||||||
|
|
||||||
stdout:read_start(function(err, data)
|
stdout:read_start(function(err, data)
|
||||||
|
if aborted then
|
||||||
|
return
|
||||||
|
end
|
||||||
assert(not err, err)
|
assert(not err, err)
|
||||||
if M.USE_QUEUE then
|
if M.USE_QUEUE then
|
||||||
queue:push(data)
|
queue:push(data)
|
||||||
|
|
|
@ -58,9 +58,17 @@ function Async:init(fn)
|
||||||
return M.add(self)
|
return M.add(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Async:aborted()
|
||||||
|
return self._aborted
|
||||||
|
end
|
||||||
|
|
||||||
function Async:_done()
|
function Async:_done()
|
||||||
|
if self._co == nil then
|
||||||
|
return
|
||||||
|
end
|
||||||
self:_emit("done")
|
self:_emit("done")
|
||||||
self._fn = nil
|
self._fn = nil
|
||||||
|
M._threads[self._co] = nil
|
||||||
self._co = nil
|
self._co = nil
|
||||||
self._on = {}
|
self._on = {}
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,7 +9,7 @@ M.__index = M
|
||||||
|
|
||||||
function M.new()
|
function M.new()
|
||||||
local self = setmetatable({}, M)
|
local self = setmetatable({}, M)
|
||||||
self.first, self.last, self.queue = 0, -1, {}
|
self:clear()
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -26,6 +26,10 @@ function M:empty()
|
||||||
return self:size() == 0
|
return self:size() == 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function M:clear()
|
||||||
|
self.first, self.last, self.queue = 0, -1, {}
|
||||||
|
end
|
||||||
|
|
||||||
function M:pop()
|
function M:pop()
|
||||||
if self:empty() then
|
if self:empty() then
|
||||||
return
|
return
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue