feat: Improve filtering ideas for sorters.
This commit is contained in:
@@ -20,6 +20,8 @@ local ngram_highlighter = function(ngram_len, prompt, display)
|
||||
return highlights
|
||||
end
|
||||
|
||||
local FILTERED = -1
|
||||
|
||||
|
||||
local Sorter = {}
|
||||
Sorter.__index = Sorter
|
||||
@@ -39,12 +41,68 @@ function Sorter:new(opts)
|
||||
state = {},
|
||||
scoring_function = opts.scoring_function,
|
||||
highlighter = opts.highlighter,
|
||||
discard = opts.discard,
|
||||
_discard_state = {
|
||||
filtered = {},
|
||||
prompt = '',
|
||||
},
|
||||
}, Sorter)
|
||||
end
|
||||
|
||||
-- TODO: We could make this a bit smarter and cache results "as we go" and where they got filtered.
|
||||
-- Then when we hit backspace, we don't have to re-caculate everything.
|
||||
-- Prime did a lot of the hard work already, but I don't want to copy as much memory around
|
||||
-- as he did in his example.
|
||||
-- Example can be found in ./scratch/prime_prompt_cache.lua
|
||||
function Sorter:_start(prompt)
|
||||
if not self.discard then
|
||||
return
|
||||
end
|
||||
|
||||
local previous = self._discard_state.prompt
|
||||
local len_previous = #previous
|
||||
|
||||
if #prompt < len_previous then
|
||||
log.debug("Reset discard because shorter prompt")
|
||||
self._discard_state.filtered = {}
|
||||
elseif string.sub(prompt, 1, len_previous) ~= previous then
|
||||
log.debug("Reset discard no match")
|
||||
self._discard_state.filtered = {}
|
||||
end
|
||||
|
||||
self._discard_state.prompt = prompt
|
||||
end
|
||||
|
||||
-- TODO: Consider doing something that makes it so we can skip the filter checks
|
||||
-- if we're not discarding. Also, that means we don't have to check otherwise as well :)
|
||||
function Sorter:score(prompt, entry)
|
||||
if not entry or not entry.ordinal then return -1 end
|
||||
return self:scoring_function(prompt or "", entry.ordinal, entry)
|
||||
|
||||
local ordinal = entry.ordinal
|
||||
|
||||
if self:_was_discarded(prompt, ordinal) then
|
||||
return FILTERED
|
||||
end
|
||||
|
||||
local score = self:scoring_function(prompt or "", ordinal, entry)
|
||||
|
||||
if score == FILTERED then
|
||||
self:_mark_discarded(prompt, ordinal)
|
||||
end
|
||||
|
||||
return score
|
||||
end
|
||||
|
||||
function Sorter:_was_discarded(prompt, ordinal)
|
||||
return self.discard and self._discard_state.filtered[ordinal]
|
||||
end
|
||||
|
||||
function Sorter:_mark_discarded(prompt, ordinal)
|
||||
if not self.discard then
|
||||
return
|
||||
end
|
||||
|
||||
self._discard_state.filtered[ordinal] = true
|
||||
end
|
||||
|
||||
function sorters.new(...)
|
||||
@@ -313,6 +371,8 @@ sorters.get_fzy_sorter = function()
|
||||
local OFFSET = -fzy.get_score_floor()
|
||||
|
||||
return sorters.Sorter:new{
|
||||
discard = true,
|
||||
|
||||
scoring_function = function(_, prompt, line)
|
||||
-- Check for actual matches before running the scoring alogrithm.
|
||||
if not fzy.has_match(prompt, line) then
|
||||
|
||||
Reference in New Issue
Block a user