Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into feat/filename_first
Browse files Browse the repository at this point in the history
  • Loading branch information
delphinus committed May 1, 2024
2 parents 81abed0 + 62534e2 commit 8c1ebd9
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 2 deletions.
39 changes: 39 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,22 @@ See [default configuration](https://github.com/nvim-telescope/telescope.nvim#tel
Patterns in this table control which files are indexed (and subsequently
which you'll see in the finder results).

- `matcher` (default: `"default"`)

> ___CAUTION___<br>
> This option is highly experimental.
In default, it matches against candidates by the so-called “substr matcher”,
that is, you should input characters ordered properly. If you set here with
`"fuzzy"`, it uses [_fzy_ matcher][fzy] implemented in telescope itself, and
combines the result with recency scores. With this, you can select candidates
fully _fuzzily_, besides that, can select easily ones that has higher recency
scores.

See the discussion in https://github.com/nvim-telescope/telescope-frecency.nvim/issues/165.

[fzy]: https://github.com/jhawthorn/fzy

- `max_timestamps` (default: `10`)

Set the max count of timestamps DB keeps when you open files. It ignores the
Expand Down Expand Up @@ -245,6 +261,29 @@ See [default configuration](https://github.com/nvim-telescope/telescope.nvim#tel
}
```

- `scoring_function` (default: see below)

> ___CAUTION___<br>
> This option is highly experimental.
This will be used only when `matcher` option is `"fuzzy"`. You can customize the
logic to adjust scores between [fzy matcher][fzy] scores and recency ones.

```lua
-- the default value
---@param recency integer
---@param fzy_score number
---@return number
scoring_function = function(recency, fzy_score)
local score = (10 / (recency == 0 and 1 or recency)) - 1 / fzy_score
-- HACK: -1 means FILTERED, so return a bit smaller one.
return score == -1 and -1.000001 or score
end,
```

NOTE: telescope orders candidates in the ascending order. It also accepts
negative numbers, but `-1` means the candidates should not be shown.

- `show_filter_column` (default: `true`)

Show the path of the active filter before file paths. In default, it uses the
Expand Down
20 changes: 20 additions & 0 deletions lua/frecency/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ local Config = {}
---@field filter_delimiter string default: ":"
---@field hide_current_buffer boolean default: false
---@field ignore_patterns string[] default: { "*.git/*", "*/tmp/*", "term://*" }
---@field matcher "default"|"fuzzy" default: "default"
---@field scoring_function fun(recency: integer, fzy_score: number): number default: see lua/frecency/config.lua
---@field max_timestamps integer default: 10
---@field show_filter_column boolean|string[] default: true
---@field show_scores boolean default: false
Expand All @@ -35,6 +37,7 @@ Config.new = function()
hide_current_buffer = false,
ignore_patterns = os_util.is_windows and { [[*.git\*]], [[*\tmp\*]], "term://*" }
or { "*.git/*", "*/tmp/*", "term://*" },
matcher = "default",
max_timestamps = 10,
recency_values = {
{ age = 240, value = 100 }, -- past 4 hours
Expand All @@ -44,6 +47,14 @@ Config.new = function()
{ age = 43200, value = 20 }, -- past month
{ age = 129600, value = 10 }, -- past 90 days
},
---@param recency integer
---@param fzy_score number
---@return number
scoring_function = function(recency, fzy_score)
local score = (10 / (recency == 0 and 1 or recency)) - 1 / fzy_score
-- HACK: -1 means FILTERED, so return a bit smaller one.
return score == -1 and -1.000001 or score
end,
show_filter_column = true,
show_scores = false,
show_unindexed = true,
Expand All @@ -62,7 +73,9 @@ Config.new = function()
filter_delimiter = true,
hide_current_buffer = true,
ignore_patterns = true,
matcher = true,
max_timestamps = true,
scoring_function = true,
show_filter_column = true,
show_scores = true,
show_unindexed = true,
Expand Down Expand Up @@ -105,6 +118,13 @@ Config.setup = function(ext_config)
filter_delimiter = { opts.filter_delimiter, "s" },
hide_current_buffer = { opts.hide_current_buffer, "b" },
ignore_patterns = { opts.ignore_patterns, "t" },
matcher = {
opts.matcher,
function(v)
return type(v) == "string" and (v == "default" or v == "fuzzy")
end,
'"default" or "fuzzy"',
},
max_timestamps = {
opts.max_timestamps,
function(v)
Expand Down
11 changes: 10 additions & 1 deletion lua/frecency/entry_maker.lua
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ end
---@field ordinal string
---@field name string
---@field score number
---@field fuzzy_score? number
---@field display fun(entry: FrecencyEntry): string, table

---@class FrecencyFile
Expand Down Expand Up @@ -81,7 +82,15 @@ function EntryMaker:items(entry, workspace, workspace_tag, formatter)
local items, width_items = {}, {}
if config.show_scores then
table.insert(items, { entry.score, "TelescopeFrecencyScores" })
table.insert(width_items, { width = 8 })
table.insert(width_items, { width = 5 }) -- recency score
if config.matcher == "fuzzy" then
table.insert(items, { entry.index, "TelescopeFrecencyScores" })
table.insert(width_items, { width = 5 }) -- index
local score = (not entry.fuzzy_score or entry.fuzzy_score == 0) and "0"
or ("%.3f"):format(entry.fuzzy_score):sub(0, 5)
table.insert(items, { score, "TelescopeFrecencyScores" })
table.insert(width_items, { width = 6 }) -- fuzzy score
end
end
if self.web_devicons.is_enabled then
table.insert(items, { self.web_devicons:get_icon(entry.name, entry.name:match "%a+$", { default = true }) })
Expand Down
26 changes: 26 additions & 0 deletions lua/frecency/fuzzy_sorter.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
local config = require "frecency.config"
local sorters = require "telescope.sorters"

---@param opts any options for get_fzy_sorter()
return function(opts)
local fzy_sorter = sorters.get_fzy_sorter(opts)

return sorters.Sorter:new {
---@param prompt string
---@param entry FrecencyEntry
---@return number
scoring_function = function(_, prompt, _, entry)
if #prompt == 0 then
return 1
end
local fzy_score = fzy_sorter:scoring_function(prompt, entry.ordinal)
if fzy_score <= 0 then
return -1
end
entry.fuzzy_score = config.scoring_function(entry.score, fzy_score)
return entry.fuzzy_score
end,

highlighter = fzy_sorter.highlighter,
}
end
3 changes: 2 additions & 1 deletion lua/frecency/picker.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
local State = require "frecency.state"
local Finder = require "frecency.finder"
local config = require "frecency.config"
local fuzzy_sorter = require "frecency.fuzzy_sorter"
local sorters = require "telescope.sorters"
local log = require "plenary.log"
local Path = require "plenary.path" --[[@as FrecencyPlenaryPath]]
Expand Down Expand Up @@ -105,7 +106,7 @@ function Picker:start(opts)
prompt_title = "Frecency",
finder = finder,
previewer = config_values.file_previewer(opts),
sorter = sorters.get_substr_matcher(),
sorter = config.matcher == "default" and sorters.get_substr_matcher() or fuzzy_sorter(opts),
on_input_filter_cb = self:on_input_filter_cb(opts),
attach_mappings = function(prompt_bufnr)
return self:attach_mappings(prompt_bufnr)
Expand Down

0 comments on commit 8c1ebd9

Please sign in to comment.