diff options
Diffstat (limited to 'lua/telescope/entry_manager.lua')
| -rw-r--r-- | lua/telescope/entry_manager.lua | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/lua/telescope/entry_manager.lua b/lua/telescope/entry_manager.lua new file mode 100644 index 0000000..bca4e55 --- /dev/null +++ b/lua/telescope/entry_manager.lua @@ -0,0 +1,131 @@ +local log = require("telescope.log") + +local EntryManager = {} +EntryManager.__index = EntryManager + +function EntryManager:new(max_results, set_entry, info) + log.trace("Creating entry_manager...") + + info = info or {} + info.looped = 0 + info.inserted = 0 + + -- state contains list of + -- { + -- score = ... + -- line = ... + -- metadata ? ... + -- } + local entry_state = {} + + set_entry = set_entry or function() end + + return setmetatable({ + set_entry = set_entry, + max_results = max_results, + worst_acceptable_score = math.huge, + + entry_state = entry_state, + info = info, + + num_results = function() + return #entry_state + end, + + get_ordinal = function(self, index) + return self:get_entry(index).ordinal + end, + + get_entry = function(_, index) + return (entry_state[index] or {}).entry + end, + + get_score = function(_, index) + return (entry_state[index] or {}).score + end, + + find_entry = function(_, entry) + if entry == nil then + return nil + end + + for k, v in ipairs(entry_state) do + local existing_entry = v.entry + + -- FIXME: This has the problem of assuming that display will not be the same for two different entries. + if existing_entry.display == entry.display then + return k + end + end + + return nil + end, + + _get_state = function() + return entry_state + end, + }, self) +end + +function EntryManager:should_save_result(index) + return index <= self.max_results +end + +function EntryManager:add_entry(score, entry) + score = score or 0 + + if score >= self.worst_acceptable_score then + return + end + + for index, item in ipairs(self.entry_state) do + self.info.looped = self.info.looped + 1 + + if item.score > score then + return self:insert(index, { + score = score, + entry = entry, + }) + end + + -- Don't add results that are too bad. + if not self:should_save_result(index) then + return + end + end + + return self:insert({ + score = score, + entry = entry, + }) +end + +function EntryManager:insert(index, entry) + if entry == nil then + entry = index + index = #self.entry_state + 1 + end + + -- To insert something, we place at the next available index (or specified index) + -- and then shift all the corresponding items one place. + local next_entry, last_score + repeat + self.info.inserted = self.info.inserted + 1 + next_entry = self.entry_state[index] + + self.set_entry(index, entry.entry) + self.entry_state[index] = entry + + last_score = entry.score + + index = index + 1 + entry = next_entry + until not next_entry or not self:should_save_result(index) + + if not self:should_save_result(index) then + self.worst_acceptable_score = last_score + end +end + + +return EntryManager |
