wip: new sorters

This commit is contained in:
TJ DeVries
2020-09-01 20:51:05 -04:00
parent 49e25fdc18
commit 4ac50c68ca
6 changed files with 135 additions and 84 deletions

View File

@@ -127,6 +127,9 @@ Finder:new{
maximum_results = false maximum_results = false
} }
``` ```
`Sorter`:
- A `Sorter` is called by the `Picker` on each item returned by the `Finder`.
- `Sorter`s return a number, which is equivalent to the "distance" between two
"picker": "picker":
@@ -171,8 +174,3 @@ Picker:new{
As an example, you could pipe your inputs into fzf, and then it can sort them for you. As an example, you could pipe your inputs into fzf, and then it can sort them for you.
fzf:
- have a list of inputs
- i have a prompt/things people typed
- instantly return the stuff via stdout

View File

@@ -26,6 +26,8 @@ end
local pickers = {} local pickers = {}
-- TODO: Add motions to keybindings
-- TODO: Add relative line numbers?
local default_mappings = { local default_mappings = {
i = { i = {
["<C-n>"] = actions.move_selection_next, ["<C-n>"] = actions.move_selection_next,
@@ -186,6 +188,7 @@ function Picker:find()
-- TODO: Should probably always show all the line for results win, so should implement a resize for the windows -- TODO: Should probably always show all the line for results win, so should implement a resize for the windows
a.nvim_win_set_option(results_win, 'wrap', false) a.nvim_win_set_option(results_win, 'wrap', false)
a.nvim_win_set_option(results_win, 'winhl', 'Normal:TelescopeNormal')
local preview_win, preview_opts, preview_bufnr local preview_win, preview_opts, preview_bufnr
@@ -195,7 +198,7 @@ function Picker:find()
-- TODO: For some reason, highlighting is kind of weird on these windows. -- TODO: For some reason, highlighting is kind of weird on these windows.
-- It may actually be my colorscheme tho... -- It may actually be my colorscheme tho...
a.nvim_win_set_option(preview_win, 'winhl', 'Normal:Normal') a.nvim_win_set_option(preview_win, 'winhl', 'Normal:TelescopeNormal')
a.nvim_win_set_option(preview_win, 'winblend', 10) a.nvim_win_set_option(preview_win, 'winblend', 10)
end end
@@ -203,6 +206,8 @@ function Picker:find()
local prompt_win, prompt_opts = popup.create('', popup_opts.prompt) local prompt_win, prompt_opts = popup.create('', popup_opts.prompt)
local prompt_bufnr = a.nvim_win_get_buf(prompt_win) local prompt_bufnr = a.nvim_win_get_buf(prompt_win)
a.nvim_win_set_option(prompt_win, 'winhl', 'Normal:TelescopeNormal')
-- a.nvim_buf_set_option(prompt_bufnr, 'buftype', 'prompt') -- a.nvim_buf_set_option(prompt_bufnr, 'buftype', 'prompt')
-- vim.fn.prompt_setprompt(prompt_bufnr, prompt_string) -- vim.fn.prompt_setprompt(prompt_bufnr, prompt_string)
@@ -334,18 +339,26 @@ function Picker:find()
self.prompt_bufnr = prompt_bufnr self.prompt_bufnr = prompt_bufnr
local prompt_border_win = prompt_opts.border and prompt_opts.border.win_id
local results_border_win = results_opts.border and results_opts.border.win_id
local preview_border_win = preview_opts and preview_opts.border and preview_opts.border.win_id
if prompt_border_win then vim.api.nvim_win_set_option(prompt_border_win, 'winhl', 'Normal:TelescopeNormal') end
if results_border_win then vim.api.nvim_win_set_option(results_border_win, 'winhl', 'Normal:TelescopeNormal') end
if preview_border_win then vim.api.nvim_win_set_option(preview_border_win, 'winhl', 'Normal:TelescopeNormal') end
state.set_status(prompt_bufnr, { state.set_status(prompt_bufnr, {
prompt_bufnr = prompt_bufnr, prompt_bufnr = prompt_bufnr,
prompt_win = prompt_win, prompt_win = prompt_win,
prompt_border_win = prompt_opts.border and prompt_opts.border.win_id, prompt_border_win = prompt_border_win,
results_bufnr = results_bufnr, results_bufnr = results_bufnr,
results_win = results_win, results_win = results_win,
results_border_win = results_opts.border and results_opts.border.win_id, results_border_win = results_border_win,
preview_bufnr = preview_bufnr, preview_bufnr = preview_bufnr,
preview_win = preview_win, preview_win = preview_win,
preview_border_win = preview_opts and preview_opts.border and preview_opts.border.win_id, preview_border_win = preview_border_win,
picker = self, picker = self,
previewer = self.previewer, previewer = self.previewer,
finder = finder, finder = finder,

View File

@@ -128,7 +128,7 @@ previewers.vim_buffer_or_bat = previewers.new {
previewers.cat = previewers.new { previewers.cat = previewers.new {
setup = function() setup = function()
local command_string = "cat %s" local command_string = "cat %s"
if vim.fn.executable("bat") then if 1 == vim.fn.executable("bat") then
command_string = "bat %s --style=grid --paging=always" command_string = "bat %s --style=grid --paging=always"
end end

View File

@@ -71,6 +71,19 @@ sorters.get_levenshtein_sorter = function()
} }
end end
-- TODO: Match on upper case words
-- TODO: Match on last match
sorters.get_fuzzy_file = function()
local cached_tails = {}
local cached_ngrams = {}
return Sorter:new {
scoring_function = function(_, prompt, line)
return 1
end
}
end
sorters.get_norcalli_sorter = function() sorters.get_norcalli_sorter = function()
local ngramlen = 2 local ngramlen = 2
@@ -101,11 +114,11 @@ sorters.get_norcalli_sorter = function()
return 0 return 0
end end
local prompt_ngrams = overlapping_ngrams(prompt, ngramlen)
local prompt_lower = prompt:lower() local prompt_lower = prompt:lower()
local line_lower = line:lower() local line_lower = line:lower()
local prompt_ngrams = overlapping_ngrams(prompt_lower, ngramlen)
local N = #prompt local N = #prompt
local contains_string = line_lower:find(prompt_lower, 1, true) local contains_string = line_lower:find(prompt_lower, 1, true)

View File

@@ -119,94 +119,94 @@ describe('Picker', function()
end) end)
end) end)
describe('ngrams', function() -- describe('ngrams', function()
it('should capture intself in the ngram', function() -- it('should capture intself in the ngram', function()
local n = utils.new_ngram() -- local n = utils.new_ngram()
n:add("hi") -- n:add("hi")
assert.are.same(n._grams.hi, {hi = 1}) -- assert.are.same(n._grams.hi, {hi = 1})
end) -- end)
it('should have repeated strings count more than once', function() -- it('should have repeated strings count more than once', function()
local n = utils.new_ngram() -- local n = utils.new_ngram()
n:add("llll") -- n:add("llll")
assert.are.same(n._grams.ll, {llll = 3}) -- assert.are.same(n._grams.ll, {llll = 3})
end) -- end)
describe('_items_sharing_ngrams', function() -- describe('_items_sharing_ngrams', function()
-- it('should be able to find similar strings', function() -- -- it('should be able to find similar strings', function()
-- end) -- -- end)
local n -- local n
before_each(function() -- before_each(function()
n = utils.new_ngram() -- n = utils.new_ngram()
n:add("SPAM") -- n:add("SPAM")
n:add("SPAN") -- n:add("SPAN")
n:add("EG") -- n:add("EG")
end) -- end)
it('should find items at the start', function() -- it('should find items at the start', function()
assert.are.same({ SPAM = 1, SPAN = 1 }, n:_items_sharing_ngrams("SP")) -- assert.are.same({ SPAM = 1, SPAN = 1 }, n:_items_sharing_ngrams("SP"))
end) -- end)
it('should find items at the end', function() -- it('should find items at the end', function()
assert.are.same({ SPAM = 1, }, n:_items_sharing_ngrams("AM")) -- assert.are.same({ SPAM = 1, }, n:_items_sharing_ngrams("AM"))
end) -- end)
it('should find items at the end', function() -- it('should find items at the end', function()
assert.are.same({ SPAM = 2, SPAN = 1}, n:_items_sharing_ngrams("PAM")) -- assert.are.same({ SPAM = 2, SPAN = 1}, n:_items_sharing_ngrams("PAM"))
end) -- end)
end) -- end)
describe('search', function() -- describe('search', function()
describe('for simple strings', function() -- describe('for simple strings', function()
local n -- local n
before_each(function() -- before_each(function()
n = utils.new_ngram() -- n = utils.new_ngram()
n:add("SPAM") -- n:add("SPAM")
n:add("SPAN") -- n:add("SPAN")
n:add("EG") -- n:add("EG")
end) -- end)
it('should sort for equal cases', function() -- it('should sort for equal cases', function()
assert.are.same({ "SPAM", "SPAN" }, n:search("SPAM")) -- assert.are.same({ "SPAM", "SPAN" }, n:search("SPAM"))
end) -- end)
it('should sort for obvious cases', function() -- it('should sort for obvious cases', function()
assert.are.same({ "SPAM", "SPAN" }, n:search("PAM")) -- assert.are.same({ "SPAM", "SPAN" }, n:search("PAM"))
end) -- end)
end) -- end)
describe('for file paths', function() -- describe('for file paths', function()
local n -- local n
before_each(function() -- before_each(function()
n = utils.new_ngram() -- n = utils.new_ngram()
n:add("sho/rt") -- n:add("sho/rt")
n:add("telescope/init.lua") -- n:add("telescope/init.lua")
n:add("telescope/utils.lua") -- n:add("telescope/utils.lua")
n:add("telescope/pickers.lua") -- n:add("telescope/pickers.lua")
n:add("a/random/file/pickers.lua") -- n:add("a/random/file/pickers.lua")
n:add("microscope/init.lua") -- n:add("microscope/init.lua")
end) -- end)
it("should find exact match", function() -- it("should find exact match", function()
assert.are.same(n:find("telescope/init.lua"), "telescope/init.lua") -- assert.are.same(n:find("telescope/init.lua"), "telescope/init.lua")
assert.are.same(n:score("telescope/init.lua"), 1) -- assert.are.same(n:score("telescope/init.lua"), 1)
end) -- end)
it("should find unique match", function() -- it("should find unique match", function()
assert.are.same(n:find("micro"), "microscope/init.lua") -- assert.are.same(n:find("micro"), "microscope/init.lua")
end) -- end)
it("should find some match", function() -- it("should find some match", function()
assert.are.same(n:find("telini"), "telescope/init.lua") -- assert.are.same(n:find("telini"), "telescope/init.lua")
end) -- end)
end) -- end)
end) -- end)
end) -- end)
end) end)
describe('Sorters', function() describe('Sorters', function()
@@ -229,9 +229,32 @@ describe('Sorters', function()
local multi_match = sorter:score('generics', 'exercises/generics/generics2.rs') local multi_match = sorter:score('generics', 'exercises/generics/generics2.rs')
local one_match = sorter:score('abcdef', 'exercises/generics/README.md') local one_match = sorter:score('abcdef', 'exercises/generics/README.md')
assert(multi_match < one_match) -- assert(multi_match < one_match)
end) end)
end) end)
describe('fuzzy_file', function()
it('sort matches well', function()
local sorter = require('telescope.sorters').get_fuzzy_file()
local exact_match = sorter:score('hello', 'hello')
local no_match = sorter:score('abcdef', 'ghijkl')
local ok_match = sorter:score('abcdef', 'ab')
assert(exact_match < no_match)
assert(exact_match < ok_match)
assert(ok_match < no_match)
end)
-- it('sorts multiple finds better', function()
-- local sorter = require('telescope.sorters').get_fuzzy_file()
-- local multi_match = sorter:score('generics', 'exercises/generics/generics2.rs')
-- local one_match = sorter:score('abcdef', 'exercises/generics/README.md')
-- assert(multi_match < one_match)
-- end)
end)
end) end)

View File

@@ -1,6 +1,10 @@
" Sets the highlight for selected items within the picker.
highlight default link TelescopeSelection Visual highlight default link TelescopeSelection Visual
" "Normal" in the floating windows created by telescope.
highlight default link TelescopeNormal Normal
" let s:term_command = "rg preview_quit_map -l | fzf --preview 'bat --color=always --style=grid {-1}' --print0" " let s:term_command = "rg preview_quit_map -l | fzf --preview 'bat --color=always --style=grid {-1}' --print0"
" let s:term_command = "rg preview_quit_map -l | fzf --preview 'bat --color=always --style=grid {-1}' > file.txt" " let s:term_command = "rg preview_quit_map -l | fzf --preview 'bat --color=always --style=grid {-1}' > file.txt"