diff --git a/lua/frecency/picker.lua b/lua/frecency/picker.lua index b6f7b2d..d409f9e 100644 --- a/lua/frecency/picker.lua +++ b/lua/frecency/picker.lua @@ -2,7 +2,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 substr_sorter = require "frecency.substr_sorter" local log = require "plenary.log" local Path = require "plenary.path" --[[@as FrecencyPlenaryPath]] local actions = require "telescope.actions" @@ -106,7 +106,7 @@ function Picker:start(opts) prompt_title = "Frecency", finder = finder, previewer = config_values.file_previewer(opts), - sorter = config.matcher == "default" and sorters.get_substr_matcher() or fuzzy_sorter(opts), + sorter = config.matcher == "default" and substr_sorter() 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) diff --git a/lua/frecency/substr_sorter.lua b/lua/frecency/substr_sorter.lua new file mode 100644 index 0000000..205bed0 --- /dev/null +++ b/lua/frecency/substr_sorter.lua @@ -0,0 +1,55 @@ +-- TODO: use this module until telescope's release include this below. +-- https://github.com/nvim-telescope/telescope.nvim/pull/2950 + +local sorters = require "telescope.sorters" +local util = require "telescope.utils" + +local substr_highlighter = function(make_display) + return function(_, prompt, display) + local highlights = {} + display = make_display(prompt, display) + + local search_terms = util.max_split(prompt, "%s") + local hl_start, hl_end + + for _, word in pairs(search_terms) do + hl_start, hl_end = display:find(word, 1, true) + if hl_start then + table.insert(highlights, { start = hl_start, finish = hl_end }) + end + end + + return highlights + end +end + +return function() + local make_display = vim.o.smartcase + and function(prompt, display) + local has_upper_case = not not prompt:match "%u" + return has_upper_case and display or display:lower() + end + or function(_, display) + return display:lower() + end + + return sorters.Sorter:new { + highlighter = substr_highlighter(make_display), + scoring_function = function(_, prompt, _, entry) + if #prompt == 0 then + return 1 + end + + local display = make_display(prompt, entry.ordinal) + + local search_terms = util.max_split(prompt, "%s") + for _, word in pairs(search_terms) do + if not display:find(word, 1, true) then + return -1 + end + end + + return entry.index + end, + } +end