feat: Do a bit better sorting for command history

To be honest, I'm not 100% sure this is fantastic, but it's definitely a
step in the right direction for command history.

Closes: #150
This commit is contained in:
TJ DeVries
2020-10-08 22:31:44 -04:00
parent 7938ace0f6
commit 59497d6640
6 changed files with 59 additions and 29 deletions

View File

@@ -79,7 +79,6 @@ builtin.commands = function()
entry_maker = function(line)
return {
valid = line ~= "",
entry_type = make_entry.types.GENERIC,
value = line,
ordinal = line.name,
display = line.name
@@ -233,7 +232,6 @@ builtin.lsp_code_actions = function(opts)
entry_maker = function(line)
return {
valid = line ~= nil,
entry_type = make_entry.types.GENERIC,
value = line,
ordinal = line.idx .. line.title,
display = line.idx .. ': ' .. line.title
@@ -382,7 +380,7 @@ builtin.command_history = function(opts)
local history_list = vim.split(history_string, "\n")
local results = {}
for i = 3, #history_list do
for i = #history_list, 3, -1 do
local item = history_list[i]
local _, finish = string.find(item, "%d+ +")
table.insert(results, string.sub(item, finish + 1))
@@ -391,7 +389,7 @@ builtin.command_history = function(opts)
pickers.new(opts, {
prompt = 'Command History',
finder = finders.new_table(results),
sorter = sorters.get_generic_fuzzy_sorter(),
sorter = sorters.fuzzy_with_index_bias(),
attach_mappings = function(_, map)
map('i', '<CR>', actions.set_command_line)
@@ -399,12 +397,8 @@ builtin.command_history = function(opts)
-- TODO: Find a way to insert the text... it seems hard.
-- map('i', '<C-i>', actions.insert_value, { expr = true })
-- Please add the default mappings for me for the rest of the keys.
return true
end,
-- TODO: Adapt `help` to this.
-- previewer = previewers.cat,
}):find()
end

View File

@@ -113,7 +113,7 @@ function EntryManager:insert(picker, index, entry)
self.info.inserted = self.info.inserted + 1
next_entry = self.entry_state[index]
self.set_entry(picker, index, entry.entry)
self.set_entry(picker, index, entry.entry, entry.score)
self.entry_state[index] = entry
last_score = entry.score

View File

@@ -33,7 +33,7 @@ local JobFinder = _callable_obj()
function JobFinder:new(opts)
opts = opts or {}
assert(not opts.results, "`results` should be used with finder.new_table")
> assert(not opts.results, "`results` should be used with finder.new_table")
assert(not opts.static, "`static` should be used with finder.new_oneshot_job")
local obj = setmetatable({
@@ -238,8 +238,11 @@ function StaticFinder:new(opts)
assert(type(input_results) == 'table', "self.results must be a table")
local results = {}
for _, v in ipairs(input_results) do
table.insert(results, entry_maker(v))
for k, v in ipairs(input_results) do
local entry = entry_maker(v)
entry.index = k
table.insert(results, entry)
end
return setmetatable({ results = results }, self)

View File

@@ -741,7 +741,7 @@ function Picker:set_selection(row)
end
function Picker:entry_adder(index, entry)
function Picker:entry_adder(index, entry, score)
local row = self:get_row(index)
-- If it's less than 0, then we don't need to show it at all.
@@ -764,7 +764,11 @@ function Picker:entry_adder(index, entry)
-- This is the two spaces to manage the '> ' stuff.
-- Maybe someday we can use extmarks or floaty text or something to draw this and not insert here.
-- until then, insert two spaces
if TELESCOPE_DEBUG then
display = ' ' .. score .. display
else
display = ' ' .. display
end
self:_increment("displayed")

View File

@@ -75,6 +75,7 @@ layout_strategies.horizontal = function(self, max_columns, max_lines)
end)(self, max_columns, max_lines)
local picker_height = max_lines - 2 * height_padding
if self.previewer then
preview.width = resolve.resolve_width(layout_config.preview_width or function(_, cols)
if not self.previewer or cols < self.preview_cutoff then
return 0
@@ -86,6 +87,10 @@ layout_strategies.horizontal = function(self, max_columns, max_lines)
return 120
end
end)(self, picker_width, max_lines)
else
preview.width = 0
end
results.width = picker_width - preview.width
prompt.width = picker_width - preview.width
@@ -114,7 +119,7 @@ layout_strategies.horizontal = function(self, max_columns, max_lines)
end
return {
preview = preview.width > 0 and preview,
preview = self.previewer and preview.width > 0 and preview,
results = results,
prompt = prompt
}
@@ -174,7 +179,7 @@ layout_strategies.center = function(self, columns, lines)
preview.col = results.col
return {
preview = self.previewer and preview,
preview = self.previewer and preview.width > 0 and preview,
results = results,
prompt = prompt
}
@@ -246,7 +251,7 @@ layout_strategies.vertical = function(self, max_columns, max_lines)
end
return {
preview = preview.width > 0 and preview,
preview = self.previewer and preview.width > 0 and preview,
results = results,
prompt = prompt
}

View File

@@ -198,7 +198,7 @@ end
sorters.get_generic_fuzzy_sorter = function(opts)
opts = opts or {}
local ngram_len = 2
local ngram_len = opts.ngram_len or 2
local function overlapping_ngrams(s, n)
if TelescopeCachedNgrams[s] and TelescopeCachedNgrams[s][n] then
@@ -283,6 +283,30 @@ sorters.get_generic_fuzzy_sorter = function(opts)
}
end
sorters.fuzzy_with_index_bias = function(opts)
opts = opts or {}
opts.ngram_len = 2
-- TODO: Probably could use a better sorter here.
local fuzzy_sorter = sorters.get_generic_fuzzy_sorter(opts)
return Sorter:new {
scoring_function = function(_, prompt, _, entry)
local base_score = fuzzy_sorter:score(prompt, entry)
if base_score == -1 then
return -1
end
if base_score == 0 then
return entry.index
else
return math.min(math.pow(entry.index, 0.25), 2) * base_score
end
end
}
end
-- Bad & Dumb Sorter
sorters.get_levenshtein_sorter = function()
return Sorter:new {