mirror of
https://github.com/folke/snacks.nvim
synced 2025-08-05 03:08:13 +00:00
feat(picker.matcher): frecency and cwd bonus can now be enabled on any picker
This commit is contained in:
parent
5778234e39
commit
7b85dfc6f6
2 changed files with 20 additions and 0 deletions
|
@ -27,6 +27,7 @@ local M = {}
|
||||||
---@field [string] any
|
---@field [string] any
|
||||||
---@field idx number
|
---@field idx number
|
||||||
---@field score number
|
---@field score number
|
||||||
|
---@field frecency? number
|
||||||
---@field score_add? number
|
---@field score_add? number
|
||||||
---@field score_mul? number
|
---@field score_mul? number
|
||||||
---@field match_tick? number
|
---@field match_tick? number
|
||||||
|
@ -110,6 +111,10 @@ local defaults = {
|
||||||
sort_empty = false, -- sort results when the search string is empty
|
sort_empty = false, -- sort results when the search string is empty
|
||||||
filename_bonus = true, -- give bonus for matching file names (last part of the path)
|
filename_bonus = true, -- give bonus for matching file names (last part of the path)
|
||||||
file_pos = true, -- support patterns like `file:line:col` and `file:line`
|
file_pos = true, -- support patterns like `file:line:col` and `file:line`
|
||||||
|
-- the bonusses below, possibly require string concatenation and path normalization,
|
||||||
|
-- so this can have a performance impact for large lists and increase memory usage
|
||||||
|
cwd_bonus = false, -- give bonus for matching files in the cwd
|
||||||
|
frecency = false, -- frecency bonus
|
||||||
},
|
},
|
||||||
sort = {
|
sort = {
|
||||||
-- default sort is by score, text length and index
|
-- default sort is by score, text length and index
|
||||||
|
|
|
@ -11,10 +11,14 @@ local Async = require("snacks.picker.util.async")
|
||||||
---@field score snacks.picker.Score
|
---@field score snacks.picker.Score
|
||||||
---@field sorting? boolean
|
---@field sorting? boolean
|
||||||
---@field file? {path: string, pos: snacks.picker.Pos}
|
---@field file? {path: string, pos: snacks.picker.Pos}
|
||||||
|
---@field cwd string
|
||||||
|
---@field frecency? snacks.picker.Frecency
|
||||||
local M = {}
|
local M = {}
|
||||||
M.__index = M
|
M.__index = M
|
||||||
M.DEFAULT_SCORE = 1000
|
M.DEFAULT_SCORE = 1000
|
||||||
M.INVERSE_SCORE = 1000
|
M.INVERSE_SCORE = 1000
|
||||||
|
local BONUS_FRECENCY = 8
|
||||||
|
local BONUS_CWD = 10
|
||||||
|
|
||||||
local YIELD_MATCH = 1 -- ms
|
local YIELD_MATCH = 1 -- ms
|
||||||
|
|
||||||
|
@ -44,6 +48,7 @@ function M.new(opts)
|
||||||
self.sorting = true
|
self.sorting = true
|
||||||
self.tick = 0
|
self.tick = 0
|
||||||
self.score = require("snacks.picker.core.score").new(self.opts)
|
self.score = require("snacks.picker.core.score").new(self.opts)
|
||||||
|
self.frecency = self.opts.frecency and require("snacks.picker.core.frecency").new() or nil
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -71,6 +76,7 @@ function M:run(picker, opts)
|
||||||
self.task:abort()
|
self.task:abort()
|
||||||
picker.list:clear()
|
picker.list:clear()
|
||||||
|
|
||||||
|
self.cwd = vim.fs.normalize(picker.opts.cwd or (vim.uv or vim.loop).cwd() or ".")
|
||||||
self.sorting = not self:empty() or picker.opts.matcher.sort_empty
|
self.sorting = not self:empty() or picker.opts.matcher.sort_empty
|
||||||
|
|
||||||
-- PERF: fast path for empty pattern
|
-- PERF: fast path for empty pattern
|
||||||
|
@ -265,6 +271,15 @@ function M:update(item)
|
||||||
item.pos = self.file.pos
|
item.pos = self.file.pos
|
||||||
item.match_pos = true
|
item.match_pos = true
|
||||||
end
|
end
|
||||||
|
if item.file then
|
||||||
|
if self.frecency then
|
||||||
|
item.frecency = item.frecency or self.frecency:get(item)
|
||||||
|
score = score + (1 - 1 / (1 + item.frecency)) * BONUS_FRECENCY
|
||||||
|
end
|
||||||
|
if self.opts.cwd_bonus and self.cwd == item.cwd or Snacks.picker.util.path(item):find(self.cwd, 1, true) == 1 then
|
||||||
|
score = score + BONUS_CWD
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
item.match_tick, item.score = self.tick, score
|
item.match_tick, item.score = self.tick, score
|
||||||
return true
|
return true
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue