(F)recency sorting for all Telescope pickers.
Very hacky solution, overriding telescope internals to provide recency/frecency sorting for any picker.
- telescope.nvim (required)
- sqlite.lua (required)
- dressing.nvim (optional, for
vim.ui.select
, see here)
Timestamps and selected records are stored in an SQLite3 database for persistence and speed and accessed via sqlite.lua
.
Via lazy.nvim
{
'prochri/telescope-all-recent.nvim',
dependencies = {
"nvim-telescope/telescope.nvim",
"kkharji/sqlite.lua",
-- optional, if using telescope for vim.ui.select
"stevearc/dressing.nvim"
},
opts =
{
-- your config goes here
}
}
If you are creating keybindings to telescope via lua functions, either load this plugin first and then bind the function, or wrap the call in another function (see #2):
-- This may bind to old telescope function depending on your load order:
-- vim.keymap.set('n', '<leader>f', require'telescope'.builtins.find_files)
-- So: better wrap it in a function:
vim.keymap.set('n', '<leader>f', function() require'telescope'.builtins.find_files() end)
The default configuration should come with sane values, so you can get started right away! The following builtin pickers are activated by default:
- man_pages
- vim_options
- pickers
- builtin
- planets
- commands
- help_tags
- find_files
- git_files
- tags
- git_commits
- git_branches
There are two different sorting algorithms available. They can be set for each picker individually:
- recent: show the most recently selected items first.
- frecent: consider both the frequency and recency of the items (see telescope-frecency.nvim)
If you want to change some settings or add pickers, here is how:
require'telescope-all-recent'.setup{
database = {
folder = vim.fn.stdpath("data"),
file = "telescope-all-recent.sqlite3",
max_timestamps = 10,
},
debug = false,
scoring = {
recency_modifier = { -- also see telescope-frecency for these settings
[1] = { age = 240, value = 100 }, -- past 4 hours
[2] = { age = 1440, value = 80 }, -- past day
[3] = { age = 4320, value = 60 }, -- past 3 days
[4] = { age = 10080, value = 40 }, -- past week
[5] = { age = 43200, value = 20 }, -- past month
[6] = { age = 129600, value = 10 } -- past 90 days
},
-- how much the score of a recent item will be improved.
boost_factor = 0.0001
},
default = {
disable = true, -- disable any unkown pickers (recommended)
use_cwd = true, -- differentiate scoring for each picker based on cwd
sorting = 'recent' -- sorting: options: 'recent' and 'frecency'
},
pickers = { -- allows you to overwrite the default settings for each picker
man_pages = { -- enable man_pages picker. Disable cwd and use frecency sorting.
disable = false,
use_cwd = false,
sorting = 'frecency',
},
-- change settings for a telescope extension.
-- To find out about extensions, you can use `print(vim.inspect(require'telescope'.extensions))`
['extension_name#extension_method'] = {
-- [...]
}
}
}
The default config values can be found here.
To use all-recent for a telescope extension, find out the extensions name and picker method,
for example using print(vim.inspect(require'telescope'.extensions))
and then add this in the plugins configuration:
{
pickers = {
// ...
['extension_name#extension_method'] = {
disable = false,
use_cwd = false,
sorting = 'recent',
}
}
}
Plugins like dressing.nvim
or telescope-ui-select.nvim
allow replacing vim.ui.select
with a telescope picker.
Make sure to load telescope-all-recent.nvim after the vim.ui.select
plugin in order for this to work!
To get sorting for those kind of pickers, first find out the kind
or simply use the prompt displayed
in the picker. You can then customize pickers like this:
{
-- [..]
vim_ui_select = {
kinds = {
overseer_template = {
use_cwd = true,
prompt = "Task template",
-- include the prompt in the picker name
-- helps differentiate between same picker kinds with different prompts
name_include_prompt = true,
},
}
-- used as fallback if no kind configuration is available
prompts = {
["Load session"] = {
use_cwd = false,
}
}
This example shows a picker used by overseer.nvim
and the use of a generic session plugin only setting the prompt to Load session
.
To be able to see some internals and the deferred picker name, sorting and use of cwd, you can enable debug mode either in the settings or by calling:
:lua require'telescope-all-recent'.toggle_debug()
This will output information at log level INFO
and DEBUG
using vim.notify
.
Telescope does not provide the relevant hooks/callback functions to build this nicely. So, this plugin first stores some of the original functions and then overrides them:
- calls to
telescope.builtin
andtelescope.extensions[extension_name]
are overriden. This allows us to get the name of the called picker. - the
Picker:new
is replaced. We want to get all information we can about what picker we are dealing with. - the
Sorter:new
function is replaced to allow us to insert a custom sorting function, which boosts the scores of (f)recent items by a small amount. - the
action.select_default.__call
allows us to see, which result is finally selected and add it to the database.
All of this is done in override.lua.
The overall structure, sqlite usage and the frecency
sorting algorithm is heavily inspired by telescope-frecency.nvim.