feat: tiebreak config function (#1401)
Co-authored-by: Simon Hauser <Simon-Hauser@outlook.de>
This commit is contained in:
@@ -74,6 +74,20 @@ telescope.setup({opts}) *telescope.setup()*
|
|||||||
- "descending" (default)
|
- "descending" (default)
|
||||||
- "ascending"
|
- "ascending"
|
||||||
|
|
||||||
|
*telescope.defaults.tiebreak*
|
||||||
|
tiebreak: ~
|
||||||
|
A function that determines how to break a tie when two entries have
|
||||||
|
the same score.
|
||||||
|
Having a function that always returns false would keep the entries in
|
||||||
|
the order they are found, so existing_entry before current_entry.
|
||||||
|
Vice versa always returning true would place the current_entry
|
||||||
|
before the existing_entry.
|
||||||
|
|
||||||
|
Signature: function(current_entry, existing_entry, prompt) -> boolean
|
||||||
|
|
||||||
|
Default: function that breaks the tie based on the length of the
|
||||||
|
entry's ordinal
|
||||||
|
|
||||||
*telescope.defaults.selection_strategy*
|
*telescope.defaults.selection_strategy*
|
||||||
selection_strategy: ~
|
selection_strategy: ~
|
||||||
Determines how the cursor acts after each sort iteration.
|
Determines how the cursor acts after each sort iteration.
|
||||||
|
|||||||
@@ -153,6 +153,25 @@ append(
|
|||||||
- "ascending"]]
|
- "ascending"]]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
append(
|
||||||
|
"tiebreak",
|
||||||
|
function(current_entry, existing_entry, _)
|
||||||
|
return #current_entry.ordinal < #existing_entry.ordinal
|
||||||
|
end,
|
||||||
|
[[
|
||||||
|
A function that determines how to break a tie when two entries have
|
||||||
|
the same score.
|
||||||
|
Having a function that always returns false would keep the entries in
|
||||||
|
the order they are found, so existing_entry before current_entry.
|
||||||
|
Vice versa always returning true would place the current_entry
|
||||||
|
before the existing_entry.
|
||||||
|
|
||||||
|
Signature: function(current_entry, existing_entry, prompt) -> boolean
|
||||||
|
|
||||||
|
Default: function that breaks the tie based on the length of the
|
||||||
|
entry's ordinal]]
|
||||||
|
)
|
||||||
|
|
||||||
append(
|
append(
|
||||||
"selection_strategy",
|
"selection_strategy",
|
||||||
"reset",
|
"reset",
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ function EntryManager:_append_container(picker, new_container, should_update)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function EntryManager:add_entry(picker, score, entry)
|
function EntryManager:add_entry(picker, score, entry, prompt)
|
||||||
score = score or 0
|
score = score or 0
|
||||||
|
|
||||||
local max_res = self.max_results
|
local max_res = self.max_results
|
||||||
@@ -137,7 +137,7 @@ function EntryManager:add_entry(picker, score, entry)
|
|||||||
return self:_insert_container_before(picker, index, node, new_container)
|
return self:_insert_container_before(picker, index, node, new_container)
|
||||||
end
|
end
|
||||||
|
|
||||||
if score < 1 and container[2] == score and #entry.ordinal < #container[1].ordinal then
|
if score < 1 and container[2] == score and picker.tiebreak(entry, container[1], prompt) then
|
||||||
return self:_insert_container_before(picker, index, node, new_container)
|
return self:_insert_container_before(picker, index, node, new_container)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -105,6 +105,7 @@ function Picker:new(opts)
|
|||||||
|
|
||||||
scroll_strategy = get_default(opts.scroll_strategy, config.values.scroll_strategy),
|
scroll_strategy = get_default(opts.scroll_strategy, config.values.scroll_strategy),
|
||||||
sorting_strategy = get_default(opts.sorting_strategy, config.values.sorting_strategy),
|
sorting_strategy = get_default(opts.sorting_strategy, config.values.sorting_strategy),
|
||||||
|
tiebreak = get_default(opts.tiebreak, config.values.tiebreak),
|
||||||
selection_strategy = get_default(opts.selection_strategy, config.values.selection_strategy),
|
selection_strategy = get_default(opts.selection_strategy, config.values.selection_strategy),
|
||||||
|
|
||||||
layout_strategy = layout_strategy,
|
layout_strategy = layout_strategy,
|
||||||
@@ -1210,7 +1211,8 @@ function Picker:get_result_processor(find_id, prompt, status_updater)
|
|||||||
local count = 0
|
local count = 0
|
||||||
|
|
||||||
local cb_add = function(score, entry)
|
local cb_add = function(score, entry)
|
||||||
self.manager:add_entry(self, score, entry)
|
-- may need the prompt for tiebreak
|
||||||
|
self.manager:add_entry(self, score, entry, prompt)
|
||||||
status_updater { completed = false }
|
status_updater { completed = false }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ describe("process_result", function()
|
|||||||
it("works with one entry", function()
|
it("works with one entry", function()
|
||||||
local manager = EntryManager:new(5, nil)
|
local manager = EntryManager:new(5, nil)
|
||||||
|
|
||||||
manager:add_entry(nil, 1, "hello")
|
manager:add_entry(nil, 1, "hello", "")
|
||||||
|
|
||||||
eq(1, manager:get_score(1))
|
eq(1, manager:get_score(1))
|
||||||
end)
|
end)
|
||||||
@@ -14,8 +14,8 @@ describe("process_result", function()
|
|||||||
it("works with two entries", function()
|
it("works with two entries", function()
|
||||||
local manager = EntryManager:new(5, nil)
|
local manager = EntryManager:new(5, nil)
|
||||||
|
|
||||||
manager:add_entry(nil, 1, "hello")
|
manager:add_entry(nil, 1, "hello", "")
|
||||||
manager:add_entry(nil, 2, "later")
|
manager:add_entry(nil, 2, "later", "")
|
||||||
|
|
||||||
eq(2, manager.linked_states.size)
|
eq(2, manager.linked_states.size)
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ describe("process_result", function()
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
assert(called_count == 0)
|
assert(called_count == 0)
|
||||||
manager:add_entry(nil, 1, "hello")
|
manager:add_entry(nil, 1, "hello", "")
|
||||||
assert(called_count == 1)
|
assert(called_count == 1)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@@ -41,8 +41,8 @@ describe("process_result", function()
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
assert(called_count == 0)
|
assert(called_count == 0)
|
||||||
manager:add_entry(nil, 1, "hello")
|
manager:add_entry(nil, 1, "hello", "")
|
||||||
manager:add_entry(nil, 2, "world")
|
manager:add_entry(nil, 2, "world", "")
|
||||||
assert(called_count == 2)
|
assert(called_count == 2)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@@ -51,8 +51,8 @@ describe("process_result", function()
|
|||||||
local manager = EntryManager:new(5, function()
|
local manager = EntryManager:new(5, function()
|
||||||
called_count = called_count + 1
|
called_count = called_count + 1
|
||||||
end)
|
end)
|
||||||
manager:add_entry(nil, 5, "worse result")
|
manager:add_entry(nil, 5, "worse result", "")
|
||||||
manager:add_entry(nil, 2, "better result")
|
manager:add_entry(nil, 2, "better result", "")
|
||||||
|
|
||||||
eq("better result", manager:get_entry(1))
|
eq("better result", manager:get_entry(1))
|
||||||
eq("worse result", manager:get_entry(2))
|
eq("worse result", manager:get_entry(2))
|
||||||
@@ -65,8 +65,8 @@ describe("process_result", function()
|
|||||||
local manager = EntryManager:new(1, function()
|
local manager = EntryManager:new(1, function()
|
||||||
called_count = called_count + 1
|
called_count = called_count + 1
|
||||||
end)
|
end)
|
||||||
manager:add_entry(nil, 2, "better result")
|
manager:add_entry(nil, 2, "better result", "")
|
||||||
manager:add_entry(nil, 5, "worse result")
|
manager:add_entry(nil, 5, "worse result", "")
|
||||||
|
|
||||||
eq("better result", manager:get_entry(1))
|
eq("better result", manager:get_entry(1))
|
||||||
eq(1, called_count)
|
eq(1, called_count)
|
||||||
@@ -92,7 +92,8 @@ describe("process_result", function()
|
|||||||
rawset(t, k, val)
|
rawset(t, k, val)
|
||||||
return val
|
return val
|
||||||
end,
|
end,
|
||||||
})
|
}),
|
||||||
|
""
|
||||||
)
|
)
|
||||||
|
|
||||||
eq("wow", manager:get_ordinal(1))
|
eq("wow", manager:get_ordinal(1))
|
||||||
@@ -105,9 +106,9 @@ describe("process_result", function()
|
|||||||
it("should not loop a bunch", function()
|
it("should not loop a bunch", function()
|
||||||
local info = {}
|
local info = {}
|
||||||
local manager = EntryManager:new(5, nil, info)
|
local manager = EntryManager:new(5, nil, info)
|
||||||
manager:add_entry(nil, 4, "better result")
|
manager:add_entry(nil, 4, "better result", "")
|
||||||
manager:add_entry(nil, 3, "better result")
|
manager:add_entry(nil, 3, "better result", "")
|
||||||
manager:add_entry(nil, 2, "better result")
|
manager:add_entry(nil, 2, "better result", "")
|
||||||
|
|
||||||
-- Loops once to find 3 < 4
|
-- Loops once to find 3 < 4
|
||||||
-- Loops again to find 2 < 3
|
-- Loops again to find 2 < 3
|
||||||
@@ -117,9 +118,9 @@ describe("process_result", function()
|
|||||||
it("should not loop a bunch, part 2", function()
|
it("should not loop a bunch, part 2", function()
|
||||||
local info = {}
|
local info = {}
|
||||||
local manager = EntryManager:new(5, nil, info)
|
local manager = EntryManager:new(5, nil, info)
|
||||||
manager:add_entry(nil, 4, "better result")
|
manager:add_entry(nil, 4, "better result", "")
|
||||||
manager:add_entry(nil, 2, "better result")
|
manager:add_entry(nil, 2, "better result", "")
|
||||||
manager:add_entry(nil, 3, "better result")
|
manager:add_entry(nil, 3, "better result", "")
|
||||||
|
|
||||||
-- Loops again to find 2 < 4
|
-- Loops again to find 2 < 4
|
||||||
-- Loops once to find 3 > 2
|
-- Loops once to find 3 > 2
|
||||||
@@ -129,9 +130,9 @@ describe("process_result", function()
|
|||||||
|
|
||||||
it("should update worst score in all append case", function()
|
it("should update worst score in all append case", function()
|
||||||
local manager = EntryManager:new(2, nil)
|
local manager = EntryManager:new(2, nil)
|
||||||
manager:add_entry(nil, 2, "result 2")
|
manager:add_entry(nil, 2, "result 2", "")
|
||||||
manager:add_entry(nil, 3, "result 3")
|
manager:add_entry(nil, 3, "result 3", "")
|
||||||
manager:add_entry(nil, 4, "result 4")
|
manager:add_entry(nil, 4, "result 4", "")
|
||||||
|
|
||||||
eq(3, manager.worst_acceptable_score)
|
eq(3, manager.worst_acceptable_score)
|
||||||
end)
|
end)
|
||||||
@@ -141,9 +142,9 @@ describe("process_result", function()
|
|||||||
local manager = EntryManager:new(2, function()
|
local manager = EntryManager:new(2, function()
|
||||||
called_count = called_count + 1
|
called_count = called_count + 1
|
||||||
end)
|
end)
|
||||||
manager:add_entry(nil, 5, "worse result")
|
manager:add_entry(nil, 5, "worse result", "")
|
||||||
manager:add_entry(nil, 4, "less worse result")
|
manager:add_entry(nil, 4, "less worse result", "")
|
||||||
manager:add_entry(nil, 2, "better result")
|
manager:add_entry(nil, 2, "better result", "")
|
||||||
|
|
||||||
-- Once for insert 5
|
-- Once for insert 5
|
||||||
-- Once for prepend 4
|
-- Once for prepend 4
|
||||||
@@ -153,4 +154,36 @@ describe("process_result", function()
|
|||||||
eq("better result", manager:get_entry(1))
|
eq("better result", manager:get_entry(1))
|
||||||
eq(4, manager.worst_acceptable_score)
|
eq(4, manager.worst_acceptable_score)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it("should call tiebreaker if score is the same, sort length", function()
|
||||||
|
local manager = EntryManager:new(5, nil)
|
||||||
|
local picker = {
|
||||||
|
tiebreak = function(curr, prev, prompt)
|
||||||
|
eq("asdf", prompt)
|
||||||
|
return #curr < #prev
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
manager:add_entry(picker, 0.5, "same same", "asdf")
|
||||||
|
manager:add_entry(picker, 0.5, "same", "asdf")
|
||||||
|
|
||||||
|
eq("same", manager:get_entry(1))
|
||||||
|
eq("same same", manager:get_entry(2))
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("should call tiebreaker if score is the same, keep initial", function()
|
||||||
|
local manager = EntryManager:new(5, nil)
|
||||||
|
local picker = {
|
||||||
|
tiebreak = function(_, _, prompt)
|
||||||
|
eq("asdf", prompt)
|
||||||
|
return false
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
manager:add_entry(picker, 0.5, "same same", "asdf")
|
||||||
|
manager:add_entry(picker, 0.5, "same", "asdf")
|
||||||
|
|
||||||
|
eq("same", manager:get_entry(2))
|
||||||
|
eq("same same", manager:get_entry(1))
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
|||||||
Reference in New Issue
Block a user