Skip to content

Commit 4eac80d

Browse files
committed
fix(debounce): fix small buf debounce issue, add more docs
1 parent 6134070 commit 4eac80d

1 file changed

Lines changed: 48 additions & 36 deletions

File tree

lua/fuzzy/picker.lua

Lines changed: 48 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -805,48 +805,60 @@ function Picker:_flush_direct()
805805
self._state.matching = {}
806806
end
807807
local match_state = self._state.matching
808-
if match_state.debounced == nil then
809-
match_state.debounced = utils.debounce_callback(
810-
self._options.match_debounce,
811-
function(mode, list, match_query, total)
812-
local current = self.select:query()
813-
if current ~= match_query or current == "" then
814-
return
815-
end
816-
self.match:match(list, match_query, function(matching)
817-
if matching == nil then
818-
if not self.match:isvalid() or self.match:isempty() then
819-
local current_state = self._state.matching
820-
local accum = current_state and current_state.accum
821-
if not accum or #accum[1] == 0 then
822-
self.select:list(
823-
utils.EMPTY_TABLE,
824-
utils.EMPTY_TABLE
825-
)
826-
self.select:status("0/0")
827-
self.select:list(nil, nil)
828-
end
808+
if match_state.worker == nil then
809+
match_state.worker = function(list, match_query, total)
810+
-- since this call is sometimes debounced we want to minimize the chance of doing extra work, in case the query has
811+
-- changed in between the call of this callback and it actually execting, we can skip it, the finalization above
812+
-- will ensure that the check should_match will trigger the final matching if needed.
813+
local current = assert(self.select:query())
814+
if #current == 0 or current ~= match_query then
815+
return
816+
end
817+
-- start a new matcher with a non-empty query, against the target list that list will either be the entire stream
818+
-- accumulated so far, or just the latest chunk from the stream,
819+
self.match:match(list, match_query, function(matching)
820+
if matching == nil then
821+
if not self.match:isvalid() or self.match:isempty() then
822+
local matching_state = self._state.matching or {}
823+
local accum = matching_state and matching_state.accum
824+
if not accum or #accum[1] == 0 then
825+
self.select:list(
826+
utils.EMPTY_TABLE,
827+
utils.EMPTY_TABLE
828+
)
829+
self.select:status("0/0")
830+
self.select:list(nil, nil)
829831
end
830-
else
831-
if mode == "all" then self:_running_match() end
832-
matching = self:_running_match(matching, match_query)
833-
self.select:list(matching[1], matching[2])
834-
self.select:status(string.format(
835-
"%d/%d", #matching[1], total
836-
))
837832
end
838-
end, self._state.display)
839-
end
840-
)
833+
else
834+
-- the running match will ensure to reset the state internally in case the query was any different than
835+
-- it is currently stored with the matching state, the matching argument here will either be all results
836+
-- or the current streaming buffer based on the call site of this callback
837+
matching = self:_running_match(matching, match_query)
838+
self.select:list(matching[1], matching[2])
839+
self.select:status(string.format(
840+
"%d/%d", #matching[1], total
841+
))
842+
end
843+
end, self._state.display)
844+
end
845+
match_state.workerd = utils.debounce_callback(
846+
self._options.match_debounce, match_state.worker)
841847
end
842848

843849
-- If the query changed we have to do a match on all stream entries thus far, to reflect the matching state of these entries
844-
-- while the stream is still emitting
845-
local query_changed = not match_state or match_state.query ~= query
846-
if query_changed and #all > 0 then
847-
match_state.debounced("all", all, query, #all)
850+
-- while the stream is still emitting. We have two options here the query changed and we have to match on the entire set of
851+
-- results, or keep matching the incoming chunks of the stream and merge with current running match results, since the query
852+
-- never changed
853+
local match_all = not match_state or match_state.query ~= query
854+
if match_all and #all > 0 then
855+
-- debounce match onto all stream results, it is safe to debounce this call because we always have access to the latest
856+
-- accumulated results
857+
match_state.workerd(all, query, #all)
848858
elseif buf and #buf > 0 then
849-
match_state.debounced("buf", buf, query, #all)
859+
-- directly call non-debounced accumulate match worker for the current buffer, it is not safe to debounce this call as
860+
-- the buffer we receive here will no longer be available and and we can not afford to skip it
861+
match_state.worker(buf, query, #all)
850862
end
851863
else
852864
-- No query, render all of the results as-is and reset any running accumulator, as it will have become

0 commit comments

Comments
 (0)