1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
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
|