Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,15 @@ to a tag): **2.0.0 is a breaking release.**
`reference_time + last_accessed` to get the most-recent access epoch (single
value). The `count` field is preserved as an alias for `num_accesses`.
- The `db_version` config option is removed.
- Asynchronous I/O now comes from a module vendored inside `telescope.nvim`
(`neoplen`), so loading this plugin non-lazily also loads `telescope.nvim` at
`VimEnter`. The startup DB warm-up used to be a minimal `frecency` + `plenary`
load; it now unavoidably pulls in `telescope.nvim`, so it is deferred to
`VimEnter` to keep that load off Neovim's startup path. Keeping
`telescope.nvim` fully lazy while loading this plugin eagerly to register
startup buffers is no longer possible; set `bootstrap = false` to keep
telescope from loading until you open a picker. This will become possible
again once `vim.async` lands in Neovim core.

If you want the previous behaviour (v1 algorithm, Neovim 0.10.x support), pin
to the v1 line:
Expand Down
33 changes: 25 additions & 8 deletions doc/telescope-frecency.txt
Original file line number Diff line number Diff line change
Expand Up @@ -377,10 +377,19 @@ This will be called by |telescope.nvim| for its initialization. You can also
call this to initialize this plugin separated from |telescope.nvim|'s
initialization phase.

This is useful when you want to load |telescope.nvim| lazily, but to load
this plugin non-lazily (recommended way). If you load this plugin lazily,
opened buffers at the same time in Neovim launching will not be registered
into DB. Example configuration for |lazy.nvim| is below.
Loading this plugin non-lazily is the recommended way: it lets the plugin
register buffers that are opened while Neovim is launching. If you load this
plugin lazily, those buffers will not be registered into DB. Example
configuration for |lazy.nvim| is below.

NOTE: Since 2.0.0 the asynchronous I/O is provided by a module vendored inside
|telescope.nvim| (`neoplen`). Loading this plugin non-lazily therefore also
loads |telescope.nvim| itself at |VimEnter|. The startup DB warm-up used to be a
minimal load (this plugin + plenary); it now unavoidably loads |telescope.nvim|,
so it is deferred to |VimEnter| to keep that load off Neovim's startup path.
Keeping |telescope.nvim| fully lazy while this plugin registers startup buffers
is no longer possible; it will become possible again once `vim.async` lands in
Neovim core.
>lua
{
"nvim-telescope/telescope-frecency.nvim",
Expand All @@ -395,7 +404,9 @@ into DB. Example configuration for |lazy.nvim| is below.

{
"nvim-telescope/telescope.nvim",
-- `cmd` opts makes lazy.nvim load telescope.nvim lazily.
-- `cmd` opts makes lazy.nvim load telescope.nvim on the `Telescope`
-- command. Note that since 2.0.0 telescope.nvim is additionally loaded
-- at VimEnter when frecency registers startup buffers (see setup() note).
cmd = { "Telescope" },
config = function()
local telescope = require "telescope"
Expand Down Expand Up @@ -478,9 +489,15 @@ bootstrap ~
Default: `true`
Type: `boolean`

If `true` and you set this plugin to be loaded non-lazily, it initializes DB in
Neovim startup (before |VimEnter|). This initialization logic works
asynchronously and does not block Neovim's starting process.
If `true` and you set this plugin to be loaded non-lazily, it initializes DB at
|VimEnter|. This initialization logic works asynchronously and does not block
Neovim's starting process.

NOTE: Since 2.0.0 this initialization is deferred to |VimEnter| (it previously
ran earlier in startup) and, because the DB uses async I/O vendored inside
|telescope.nvim| (`neoplen`), it also loads |telescope.nvim| at VimEnter. Set
this to `false` if you want to keep telescope.nvim from loading until you
actually open a picker.

*telescope-frecency-configuration-db_root*
db_root ~
Expand Down
2 changes: 1 addition & 1 deletion lua/frecency/file_lock.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
local log = require "frecency.log"
local lazy_require = require "frecency.lazy_require"
local async = lazy_require "plenary.async" --[[@as FrecencyPlenaryAsync]]
local async = lazy_require "neoplen.async" --[[@as FrecencyPlenaryAsync]]

---@class FrecencyFileLock
---@field base string
Expand Down
2 changes: 1 addition & 1 deletion lua/frecency/finder.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ local log = require "frecency.log"
local timer = require "frecency.timer"
local lazy_require = require "frecency.lazy_require"
local Sorter = require "frecency.sorter"
local async = lazy_require "plenary.async" --[[@as FrecencyPlenaryAsync]]
local async = lazy_require "neoplen.async" --[[@as FrecencyPlenaryAsync]]

---@class FrecencyFinder
---@field config FrecencyFinderConfig
Expand Down
2 changes: 1 addition & 1 deletion lua/frecency/fs.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ local config = require "frecency.config"
local os_util = require "frecency.os_util"
local log = require "frecency.log"
local lazy_require = require "frecency.lazy_require"
local async = lazy_require "plenary.async" --[[@as FrecencyPlenaryAsync]]
local async = lazy_require "neoplen.async" --[[@as FrecencyPlenaryAsync]]

---@class FrecencyFS
local M = {
Expand Down
42 changes: 36 additions & 6 deletions lua/frecency/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,28 @@ local frecency = setmetatable({}, {
})

local function async_call(f, ...)
require("plenary.async").void(f)(...)
require("neoplen.async").void(f)(...)
end

-- Run an async call now, or defer it to |VimEnter| when still in the startup
-- phase. `neoplen.async` lives inside telescope.nvim, so calling it makes
-- lazy-loading plugin managers load telescope.nvim. There is no longer any
-- reason to do that before VimEnter -- the async DB work still finishes well
-- before the first picker either way -- while doing it mid-startup would drag
-- telescope's load onto Neovim's startup critical path. So during startup we
-- defer to VimEnter.
local function async_call_or_defer(f, ...)
if vim.v.vim_did_enter == 1 then
async_call(f, ...)
return
end
local args = { ... }
vim.api.nvim_create_autocmd("VimEnter", {
once = true,
callback = function()
async_call(f, unpack(args))
end,
})
end

local setup_done = false
Expand Down Expand Up @@ -92,7 +113,7 @@ local function setup(ext_config)
if is_floatwin or (config.ignore_register and config.ignore_register(args.buf)) then
return
end
async_call(frecency.register, args.buf, vim.api.nvim_buf_get_name(args.buf))
async_call_or_defer(frecency.register, args.buf, vim.api.nvim_buf_get_name(args.buf))
end,
})

Expand All @@ -109,10 +130,19 @@ local function setup(ext_config)
end

if config.bootstrap and vim.v.vim_did_enter == 0 then
database = require("frecency.database").create()
async_call(function()
database:start()
end)
-- Defer DB bootstrap to VimEnter: creating the DB touches neoplen.async,
-- which loads telescope. VimEnter still warms the DB before the first picker
-- while keeping that load off Neovim's startup path. See async_call_or_defer
-- above.
vim.api.nvim_create_autocmd("VimEnter", {
once = true,
callback = function()
async_call(function()
database = require("frecency.database").create()
database:start()
end)
end,
})
end

setup_done = true
Expand Down
2 changes: 1 addition & 1 deletion lua/frecency/klass.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ local log = require "frecency.log"
local timer = require "frecency.timer"
local wait = require "frecency.wait"
local lazy_require = require "frecency.lazy_require"
local async = lazy_require "plenary.async" --[[@as FrecencyPlenaryAsync]]
local async = lazy_require "neoplen.async" --[[@as FrecencyPlenaryAsync]]

---@enum FrecencyStatus
local STATUS = {
Expand Down
2 changes: 1 addition & 1 deletion lua/frecency/log.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
local config = require "frecency.config"
local lazy_require = require "frecency.lazy_require"
local log = lazy_require "plenary.log"
local log = lazy_require "neoplen.log"

return setmetatable({}, {
__index = function(_, key)
Expand Down
4 changes: 2 additions & 2 deletions lua/frecency/tests/database_spec.lua
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
local Database = require "frecency.database"
local config = require "frecency.config"
local async = require "plenary.async" --[[@as FrecencyPlenaryAsync]]
local async = require "neoplen.async" --[[@as FrecencyPlenaryAsync]]
local util = require "frecency.tests.util"
async.tests.add_to_env()
util.add_async_to_env()

local function with_database(f)
local dir, close = util.tmpdir()
Expand Down
4 changes: 2 additions & 2 deletions lua/frecency/tests/file_lock_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
local config = require "frecency.config"
local FileLock = require "frecency.file_lock"
local util = require "frecency.tests.util"
local async = require "plenary.async" --[[@as FrecencyPlenaryAsync]]
require("plenary.async").tests.add_to_env()
local async = require "neoplen.async" --[[@as FrecencyPlenaryAsync]]
util.add_async_to_env()

config.setup { debug = true }

Expand Down
2 changes: 1 addition & 1 deletion lua/frecency/tests/frecency_validate_database_spec.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
local util = require "frecency.tests.util"
local async = require "plenary.async"
local async = require "neoplen.async"

local filepath = util.filepath
local make_epoch = util.make_epoch
Expand Down
30 changes: 28 additions & 2 deletions lua/frecency/tests/util.lua
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
---@diagnostic disable: invisible, undefined-field
-- luacheck: globals describe it pending before_each after_each
local Frecency = require "frecency.klass"
local Picker = require "frecency.picker"
local config = require "frecency.config"
local log = require "plenary.log"
local async = require "plenary.async" --[[@as FrecencyPlenaryAsync]]
local log = require "neoplen.log"
local async = require "neoplen.async" --[[@as FrecencyPlenaryAsync]]
local Path = require "plenary.path"
local Job = require "plenary.job"
local wait = require "frecency.wait"
Expand Down Expand Up @@ -199,7 +200,32 @@ local function with_fake_vim_ui_select(choice, callback)
vim.ui.select = original_vim_ui_select
end

-- Replacement for `require("plenary.async").tests.add_to_env()` — neoplen
-- removed the `async.tests` submodule, so we inline the minimal helpers that
-- frecency's spec files use (`a.describe` / `a.it` / `a.before_each` /
-- `a.after_each` / `a.pending`). Sets `_G.a` so call sites resolve through the
-- global table the same way `setfenv`-based add_to_env did.
local function add_async_to_env()
local timeout = tonumber(vim.env.PLENARY_TEST_TIMEOUT)
_G.a = {
describe = describe,
it = function(s, async_func)
it(s, async.util.will_block(async_func, timeout))
end,
pending = function(async_func)
pending(async_func)
end,
before_each = function(async_func)
before_each(async.util.will_block(async_func))
end,
after_each = function(async_func)
after_each(async.util.will_block(async_func))
end,
}
end

return {
add_async_to_env = add_async_to_env,
filepath = filepath,
make_epoch = make_epoch,
make_register = make_register,
Expand Down
2 changes: 1 addition & 1 deletion lua/frecency/v2/database.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ local os_util = require "frecency.os_util"
local timer = require "frecency.timer"
local watcher = require "frecency.watcher"
local lazy_require = require "frecency.lazy_require"
local async = lazy_require "plenary.async" --[[@as FrecencyPlenaryAsync]]
local async = lazy_require "neoplen.async" --[[@as FrecencyPlenaryAsync]]

-- todo(clason): remove when dropping support for Nvim 0.12
local npcall = vim.npcall or vim.F.npcall
Expand Down
2 changes: 1 addition & 1 deletion lua/frecency/v2/table.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ local log = require "frecency.log"
local timer = require "frecency.timer"
local wait = require "frecency.wait"
local lazy_require = require "frecency.lazy_require"
local async = lazy_require "plenary.async" --[[@as FrecencyPlenaryAsync]]
local async = lazy_require "neoplen.async" --[[@as FrecencyPlenaryAsync]]

-- v1 record / data shape kept here because TableV2:from_v1 still consumes
-- them for the v1 → v2 migration in 2.0.0.
Expand Down
3 changes: 2 additions & 1 deletion lua/frecency/wait.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
local async = require "plenary.async"
local lazy_require = require "frecency.lazy_require"
local async = lazy_require "neoplen.async" --[[@as FrecencyPlenaryAsync]]

---@class FrecencyWait
---@field config FrecencyWaitConfig
Expand Down
2 changes: 1 addition & 1 deletion lua/frecency/watcher.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
local log = require "frecency.log"
local lazy_require = require "frecency.lazy_require"
local async = lazy_require "plenary.async" --[[@as FrecencyPlenaryAsync]]
local async = lazy_require "neoplen.async" --[[@as FrecencyPlenaryAsync]]

---@class FrecencyWatcherMtime
---@field sec integer
Expand Down
Loading