Skip to content

Commit

Permalink
perf(feed): use isolated memory space for resume across different nvi…
Browse files Browse the repository at this point in the history
…m instances (#549)
  • Loading branch information
linrongbin16 authored Jan 4, 2024
1 parent 7185bb0 commit 5c29cc4
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 56 deletions.
101 changes: 67 additions & 34 deletions lua/fzfx/detail/fzf_helpers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ local termcolors = require("fzfx.commons.termcolors")
local strings = require("fzfx.commons.strings")
local jsons = require("fzfx.commons.jsons")
local fileios = require("fzfx.commons.fileios")
local tables = require("fzfx.commons.tables")

local shells = require("fzfx.lib.shells")
local log = require("fzfx.lib.log")
Expand Down Expand Up @@ -88,62 +89,92 @@ end

-- visual select }

-- command feed {

--- @alias fzfx.LastQueryCacheObj {default_provider:string,query:string}
--- @type table<string, fzfx.LastQueryCacheObj>
local LAST_QUERY_CACHES = {}

--- @param name string
local function make_last_query_cache(name)
local function last_query_cache_name(name)
return paths.join(
conf.get_config().cache.dir,
string.format("_%s_last_query_cache", name)
)
end

--- @param name string
--- @return fzfx.LastQueryCacheObj?
local function get_last_query_cache(name)
if LAST_QUERY_CACHES[name] == nil then
local cache_filename = last_query_cache_name(name)
local data = fileios.readfile(cache_filename, { trim = true }) --[[@as string]]
if strings.not_empty(data) then
--- @type boolean, fzfx.LastQueryCacheObj?
local ok, data_obj = pcall(jsons.decode, data)
if
ok
and tables.tbl_not_empty(data_obj)
and strings.not_empty(tables.tbl_get(data_obj, "default_provider"))
then
LAST_QUERY_CACHES[name] = {
---@diagnostic disable-next-line: need-check-nil
default_provider = data_obj.default_provider,
---@diagnostic disable-next-line: need-check-nil
query = data_obj.query or "",
}
end
end
end
return LAST_QUERY_CACHES[name]
end

--- @param name string
--- @param query string
--- @param default_provider string
local function save_last_query_cache(name, query, default_provider)
log.ensure(
strings.not_empty(default_provider),
"|save_last_query_cache| %s default_provider must not be empty:%s, query:%s",
vim.inspect(name),
vim.inspect(default_provider),
vim.inspect(query)
)
LAST_QUERY_CACHES[name] = {
default_provider = default_provider,
query = query or "",
}
end

--- @param feed_type fzfx.CommandFeed
--- @param input_args string?
--- @param pipeline_name string
--- @return string, string?
--- @return {query:string, default_provider:string?}
local function get_command_feed(feed_type, input_args, pipeline_name)
feed_type = string.lower(feed_type)
if feed_type == "args" then
return input_args or "", nil
return { query = input_args or "" }
elseif feed_type == "visual" then
return _visual_select()
return { query = _visual_select() }
elseif feed_type == "cword" then
---@diagnostic disable-next-line: return-type-mismatch
return vim.fn.expand("<cword>"), nil
return { query = vim.fn.expand("<cword>") }
elseif feed_type == "put" then
local y = yanks.get_yank()
return (y ~= nil and type(y.regtext) == "string") and y.regtext or "", nil
return {
query = (y ~= nil and type(y.regtext) == "string") and y.regtext or "",
}
elseif feed_type == "resume" then
local cache = make_last_query_cache(pipeline_name)
local data = fileios.readfile(cache, { trim = true })
-- log.debug(
-- "|fzfx.fzf_helpers - get_command_feed| pipeline %s cache:%s",
-- vim.inspect(pipeline_name),
-- vim.inspect(data)
-- )
if
type(data) ~= "string"
or string.len(data) == 0
or not strings.startswith(data, "{")
or not strings.endswith(data, "}")
then
return "", nil
end
--- @alias fzfx.LastQueryCacheObj {default_provider:string,query:string}
local ok, obj = pcall(jsons.decode, data) --[[@as fzfx.LastQueryCacheObj]]
if ok and type(obj) == "table" then
return obj.query or "", obj.default_provider
else
return "", nil
end
local last_cache_obj = get_last_query_cache(pipeline_name) --[[@as fzfx.LastQueryCacheObj]]
return last_cache_obj or { query = "" }
else
log.throw(
"|get_command_feed| invalid command feed type! %s",
vim.inspect(feed_type)
)
return ""
log.throw("invalid command feed type: %s", vim.inspect(feed_type))
return { query = "" }
end
end

-- command feed }

-- fzf opts {

--- @return fzfx.FzfOpt[]
Expand Down Expand Up @@ -383,7 +414,9 @@ end
local M = {
_get_visual_lines = _get_visual_lines,
_visual_select = _visual_select,
make_last_query_cache = make_last_query_cache,
last_query_cache_name = last_query_cache_name,
get_last_query_cache = get_last_query_cache,
save_last_query_cache = save_last_query_cache,
get_command_feed = get_command_feed,
preprocess_fzf_opts = preprocess_fzf_opts,
_generate_fzf_color_opts = _generate_fzf_color_opts,
Expand Down
26 changes: 19 additions & 7 deletions lua/fzfx/detail/general.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1061,7 +1061,12 @@ local function general(name, query, bang, pipeline_configs, default_pipeline)
for _, rpc_id in ipairs(rpc_registries) do
rpcserver.get_instance():unregister(rpc_id)
end
local last_query_cache = fzf_helpers.make_last_query_cache(name)
local last_query_cache = fzf_helpers.last_query_cache_name(name)
fzf_helpers.save_last_query_cache(
name,
last_query,
provider_switch.pipeline
)
local content = jsons.encode({
default_provider = provider_switch.pipeline,
query = last_query,
Expand Down Expand Up @@ -1126,12 +1131,19 @@ local function _make_user_command(
local other_args = first_space_pos ~= nil
and strings.trim(string.sub(input_args, first_space_pos))
or ""
local query, last_provider =
fzf_helpers.get_command_feed(varcfg.feed, other_args, name)

local default_provider = last_provider or varcfg.default_provider

return general(name, query, opts.bang, group_config, default_provider)
local feed_obj = fzf_helpers.get_command_feed(varcfg.feed, other_args, name)
or { query = "" }

local default_provider = feed_obj.default_provider
or varcfg.default_provider

return general(
name,
feed_obj.query,
opts.bang,
group_config,
default_provider
)
end, {
nargs = "*",
range = true,
Expand Down
67 changes: 52 additions & 15 deletions test/detail/fzf_helpers_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -14,45 +14,82 @@ describe("detail.fzf_helpers", function()
end
end)

local jsons = require("fzfx.commons.jsons")
local fileios = require("fzfx.commons.fileios")
local tables = require("fzfx.commons.tables")
local strings = require("fzfx.commons.strings")
local fzf_helpers = require("fzfx.detail.fzf_helpers")
local CommandFeedEnum = require("fzfx.schema").CommandFeedEnum
require("fzfx.config").setup()
require("fzfx.detail.module").setup()

describe("[make_last_query_cache]", function()
it("makes", function()
local actual = fzf_helpers.make_last_query_cache("test")
describe("[last_query_cache_name]", function()
it("test", function()
local actual = fzf_helpers.last_query_cache_name("test")
assert_true(strings.endswith(actual, "_test_last_query_cache"))
end)
end)
describe("[get_last_query_cache/save_last_query_cache]", function()
it("is nil before initialize", function()
local actual1 = fzf_helpers.get_last_query_cache("test1")
assert_true(actual1 == nil or type(actual1) == "table")
local actual2 = fzf_helpers.get_last_query_cache("test2")
assert_true(actual2 == nil or type(actual2) == "table")
end)
it("has value after initialize", function()
local actual1 = fzf_helpers.get_last_query_cache("test1")
assert_eq(actual1, nil)
fzf_helpers.save_last_query_cache("test1", "query", "provider")
local actual2 = fzf_helpers.get_last_query_cache("test1")
assert_eq(type(actual2), "table")
assert_eq(actual2.query, "query")
assert_eq(actual2.default_provider, "provider")
end)
it("has value if exists cache file", function()
local cache_file = fzf_helpers.last_query_cache_name("test2")
local input =
jsons.encode({ query = "query2", default_provider = "provider3" })
fileios.writefile(cache_file, input)
local actual = fzf_helpers.get_last_query_cache("test2")
assert_eq(type(actual), "table")
assert_eq(actual.query, "query2")
assert_eq(actual.default_provider, "provider3")
vim.cmd(string.format([[!rm %s]], cache_file))
end)
end)

describe("[get_command_feed]", function()
it("get normal args feed", function()
local expect = "expect"
local actual1, actual2 =
local actual =
fzf_helpers.get_command_feed(CommandFeedEnum.ARGS, "expect", "test")
assert_eq(expect, actual1)
assert_true(actual2 == nil)
assert_eq(type(actual), "table")
assert_eq(expect, actual.query)
assert_eq(actual.default_provider, nil)
end)
it("get visual select feed", function()
local actual1, actual2 =
local actual =
fzf_helpers.get_command_feed(CommandFeedEnum.VISUAL, "", "test")
assert_eq(type(actual1), "string")
assert_true(actual2 == nil)
assert_eq(type(actual), "table")
assert_eq(type(actual.query), "string")
assert_eq(actual.default_provider, nil)
end)
it("get cword feed", function()
local actual1, actual2 =
local actual =
fzf_helpers.get_command_feed(CommandFeedEnum.CWORD, "", "test")
assert_eq(type(actual1), "string")
assert_true(actual2 == nil)
assert_eq(type(actual), "table")
assert_eq(type(actual.query), "string")
assert_eq(actual.default_provider, nil)
end)
it("get resume feed", function()
local actual1, actual2 =
local actual =
fzf_helpers.get_command_feed(CommandFeedEnum.RESUME, "", "test")
assert_eq(type(actual1), "string")
assert_true(actual2 == nil or type(actual2) == "string")
assert_eq(type(actual), "table")
assert_eq(type(actual.query), "string")
assert_true(
actual.default_provider == nil
or type(actual.default_provider) == "string"
)
end)
end)

Expand Down

0 comments on commit 5c29cc4

Please sign in to comment.