feat: Combine configuration into picker.new()
This commit is contained in:
109
lua/telescope/_private/NGRam.lua
Normal file
109
lua/telescope/_private/NGRam.lua
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
local NGram = {}
|
||||||
|
NGram.__index = NGram
|
||||||
|
|
||||||
|
function NGram:new(opts)
|
||||||
|
-- TODO: Add padding
|
||||||
|
opts = opts or {}
|
||||||
|
return setmetatable({
|
||||||
|
N = opts.N or 2,
|
||||||
|
split = opts.split or "/",
|
||||||
|
_depth = 5,
|
||||||
|
_grams = setmetatable({}, utils.default_table_mt)
|
||||||
|
}, self)
|
||||||
|
end
|
||||||
|
|
||||||
|
local min = math.min
|
||||||
|
|
||||||
|
function NGram:_split(word)
|
||||||
|
local word_len = #word
|
||||||
|
|
||||||
|
local result = {}
|
||||||
|
for i = 1, word_len - 1 do
|
||||||
|
-- for j = i + (self.N - 1), min(i + self._depth - 1, word_len) do
|
||||||
|
-- table.insert(result, string.sub(word, i, j))
|
||||||
|
-- end
|
||||||
|
table.insert(result, string.sub(word, i, i + self.N - 1))
|
||||||
|
end
|
||||||
|
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
-- local function pairsByKeys (t, f)
|
||||||
|
-- local a = {}
|
||||||
|
-- for n in pairs(t) do table.insert(a, n) end
|
||||||
|
-- table.sort(a, f)
|
||||||
|
-- local i = 0 -- iterator variable
|
||||||
|
-- local iter = function () -- iterator function
|
||||||
|
-- i = i + 1
|
||||||
|
-- if a[i] == nil then return nil
|
||||||
|
-- else return a[i], t[a[i]]
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
-- return iter
|
||||||
|
-- end
|
||||||
|
|
||||||
|
function NGram:add(word)
|
||||||
|
local split_word = self:_split(word)
|
||||||
|
|
||||||
|
for _, k in ipairs(split_word) do
|
||||||
|
local counts = self._grams[k]
|
||||||
|
if counts[word] == nil then
|
||||||
|
counts[word] = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
counts[word] = counts[word] + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function NGram:_items_sharing_ngrams(query)
|
||||||
|
local split_query = self:_split(query)
|
||||||
|
|
||||||
|
-- Matched string to number of N-grams shared with the query string.
|
||||||
|
local shared = {}
|
||||||
|
|
||||||
|
local remaining = {}
|
||||||
|
|
||||||
|
for _, ngram in ipairs(split_query) do
|
||||||
|
remaining = {}
|
||||||
|
for match, count in pairs(self._grams[ngram] or {}) do
|
||||||
|
remaining[match] = remaining[match] or count
|
||||||
|
|
||||||
|
if remaining[match] > 0 then
|
||||||
|
remaining[match] = remaining[match] - 1
|
||||||
|
shared[match] = (shared[match] or 0) + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return shared
|
||||||
|
end
|
||||||
|
|
||||||
|
function NGram:search(query, show_values)
|
||||||
|
local sharing_ngrams = self:_items_sharing_ngrams(query)
|
||||||
|
|
||||||
|
local results = {}
|
||||||
|
for name, count in pairs(sharing_ngrams) do
|
||||||
|
local allgrams = #query + #name - (2 * self.N) - count + 2
|
||||||
|
table.insert(results, {name, count / allgrams})
|
||||||
|
end
|
||||||
|
|
||||||
|
table.sort(results, function(left, right)
|
||||||
|
return left[2] > right[2]
|
||||||
|
end)
|
||||||
|
|
||||||
|
if not show_values then
|
||||||
|
for k, v in ipairs(results) do
|
||||||
|
results[k] = v[1]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return results
|
||||||
|
end
|
||||||
|
|
||||||
|
function NGram:find(query)
|
||||||
|
return self:search(query)[1]
|
||||||
|
end
|
||||||
|
|
||||||
|
function NGram:score(query)
|
||||||
|
return (self:search(query, true)[1] or {})[2] or 0
|
||||||
|
end
|
||||||
@@ -8,50 +8,20 @@ local finders = require('telescope.finders')
|
|||||||
local previewers = require('telescope.previewers')
|
local previewers = require('telescope.previewers')
|
||||||
local pickers = require('telescope.pickers')
|
local pickers = require('telescope.pickers')
|
||||||
local sorters = require('telescope.sorters')
|
local sorters = require('telescope.sorters')
|
||||||
|
local utils = require('telescope.utils')
|
||||||
|
|
||||||
local builtin = {}
|
local builtin = {}
|
||||||
|
|
||||||
local ifnil = function(x, was_nil, was_not_nil) if x == nil then return was_nil else return was_not_nil end end
|
|
||||||
|
|
||||||
builtin.git_files = function(opts)
|
builtin.git_files = function(opts)
|
||||||
opts = opts or {}
|
pickers.new(opts, {
|
||||||
|
prompt = 'Git File',
|
||||||
local show_preview = ifnil(opts.show_preview, true, opts.show_preview)
|
finder = finders.new_oneshot_job({ "git", "ls-files" }),
|
||||||
|
previewer = previewers.cat,
|
||||||
local file_finder = finders.new {
|
sorter = sorters.get_norcalli_sorter(),
|
||||||
static = true,
|
}):find()
|
||||||
|
|
||||||
fn_command = function(self)
|
|
||||||
return {
|
|
||||||
command = 'git',
|
|
||||||
args = {'ls-files'}
|
|
||||||
}
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
|
|
||||||
local file_previewer = previewers.cat
|
|
||||||
|
|
||||||
local file_picker = pickers.new {
|
|
||||||
previewer = show_preview and file_previewer,
|
|
||||||
|
|
||||||
selection_strategy = opts.selection_strategy,
|
|
||||||
}
|
|
||||||
|
|
||||||
-- local file_sorter = telescope.sorters.get_ngram_sorter()
|
|
||||||
-- local file_sorter = require('telescope.sorters').get_levenshtein_sorter()
|
|
||||||
local file_sorter = sorters.get_norcalli_sorter()
|
|
||||||
|
|
||||||
file_picker:find {
|
|
||||||
prompt = 'Simple File',
|
|
||||||
finder = file_finder,
|
|
||||||
sorter = file_sorter,
|
|
||||||
|
|
||||||
border = opts.border,
|
|
||||||
borderchars = opts.borderchars,
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
builtin.live_grep = function()
|
builtin.live_grep = function(opts)
|
||||||
local live_grepper = finders.new {
|
local live_grepper = finders.new {
|
||||||
maximum_results = 1000,
|
maximum_results = 1000,
|
||||||
|
|
||||||
@@ -68,15 +38,13 @@ builtin.live_grep = function()
|
|||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
local file_previewer = previewers.vimgrep
|
pickers.new(opts, {
|
||||||
local file_picker = pickers.new {
|
prompt = 'Live Grep',
|
||||||
previewer = file_previewer
|
finder = live_grepper,
|
||||||
}
|
previewer = previewers.vimgrep,
|
||||||
|
}):find()
|
||||||
-- local file_sorter = telescope.sorters.get_ngram_sorter()
|
|
||||||
-- local file_sorter = require('telescope.sorters').get_levenshtein_sorter()
|
|
||||||
-- local file_sorter = sorters.get_norcalli_sorter()
|
|
||||||
|
|
||||||
|
-- TODO: Incorporate this.
|
||||||
-- Weight the results somehow to be more likely to be the ones that you've opened.
|
-- Weight the results somehow to be more likely to be the ones that you've opened.
|
||||||
-- local old_files = {}
|
-- local old_files = {}
|
||||||
-- for _, f in ipairs(vim.v.oldfiles) do
|
-- for _, f in ipairs(vim.v.oldfiles) do
|
||||||
@@ -102,15 +70,9 @@ builtin.live_grep = function()
|
|||||||
-- end
|
-- end
|
||||||
-- end
|
-- end
|
||||||
-- }
|
-- }
|
||||||
|
|
||||||
file_picker:find {
|
|
||||||
prompt = 'Live Grep',
|
|
||||||
finder = live_grepper,
|
|
||||||
sorter = oldfiles_sorter,
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
builtin.lsp_references = function()
|
builtin.lsp_references = function(opts)
|
||||||
local params = vim.lsp.util.make_position_params()
|
local params = vim.lsp.util.make_position_params()
|
||||||
params.context = { includeDeclaration = true }
|
params.context = { includeDeclaration = true }
|
||||||
|
|
||||||
@@ -120,87 +82,34 @@ builtin.lsp_references = function()
|
|||||||
vim.list_extend(locations, vim.lsp.util.locations_to_items(server_results.result) or {})
|
vim.list_extend(locations, vim.lsp.util.locations_to_items(server_results.result) or {})
|
||||||
end
|
end
|
||||||
|
|
||||||
local results = {}
|
local results = utils.quickfix_items_to_entries(locations)
|
||||||
for _, entry in ipairs(locations) do
|
|
||||||
local vimgrep_str = string.format(
|
|
||||||
"%s:%s:%s: %s",
|
|
||||||
vim.fn.fnamemodify(entry.filename, ":."),
|
|
||||||
entry.lnum,
|
|
||||||
entry.col,
|
|
||||||
entry.text
|
|
||||||
)
|
|
||||||
|
|
||||||
table.insert(results, {
|
|
||||||
valid = true,
|
|
||||||
value = entry,
|
|
||||||
ordinal = vimgrep_str,
|
|
||||||
display = vimgrep_str,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
if vim.tbl_isempty(results) then
|
if vim.tbl_isempty(results) then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local lsp_reference_finder = finders.new {
|
local reference_picker = pickers.new(opts, {
|
||||||
results = results
|
prompt = 'LSP References',
|
||||||
}
|
finder = finders.new_table(results),
|
||||||
|
previewer = previewers.qflist,
|
||||||
local reference_previewer = previewers.qflist
|
sorter = sorters.get_norcalli_sorter(),
|
||||||
local reference_picker = pickers.new {
|
}):find()
|
||||||
previewer = reference_previewer
|
|
||||||
}
|
|
||||||
|
|
||||||
reference_picker:find {
|
|
||||||
prompt = 'LSP References',
|
|
||||||
finder = lsp_reference_finder,
|
|
||||||
sorter = sorters.get_norcalli_sorter(),
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
builtin.quickfix = function()
|
builtin.quickfix = function(opts)
|
||||||
local locations = vim.fn.getqflist()
|
local locations = vim.fn.getqflist()
|
||||||
|
local results = utils.quickfix_items_to_entries(locations)
|
||||||
local results = {}
|
|
||||||
for _, entry in ipairs(locations) do
|
|
||||||
if not entry.filename then
|
|
||||||
entry.filename = vim.api.nvim_buf_get_name(entry.bufnr)
|
|
||||||
end
|
|
||||||
|
|
||||||
local vimgrep_str = string.format(
|
|
||||||
"%s:%s:%s: %s",
|
|
||||||
vim.fn.fnamemodify(entry.filename, ":."),
|
|
||||||
entry.lnum,
|
|
||||||
entry.col,
|
|
||||||
entry.text
|
|
||||||
)
|
|
||||||
|
|
||||||
table.insert(results, {
|
|
||||||
valid = true,
|
|
||||||
value = entry,
|
|
||||||
ordinal = vimgrep_str,
|
|
||||||
display = vimgrep_str,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
if vim.tbl_isempty(results) then
|
if vim.tbl_isempty(results) then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local quickfix_finder = finders.new {
|
pickers.new(opts, {
|
||||||
results = results
|
prompt = 'Quickfix',
|
||||||
}
|
finder = finders.new_table(results),
|
||||||
|
previewer = previewers.qflist,
|
||||||
local quickfix_previewer = previewers.qflist
|
sorter = sorters.get_norcalli_sorter(),
|
||||||
local quickfix_picker = pickers.new {
|
}):find()
|
||||||
previewer = quickfix_previewer
|
|
||||||
}
|
|
||||||
|
|
||||||
quickfix_picker:find {
|
|
||||||
prompt = 'Quickfix',
|
|
||||||
finder = quickfix_finder,
|
|
||||||
sorter = sorters.get_norcalli_sorter(),
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
builtin.grep_string = function(opts)
|
builtin.grep_string = function(opts)
|
||||||
@@ -208,42 +117,23 @@ builtin.grep_string = function(opts)
|
|||||||
|
|
||||||
local search = opts.search or vim.fn.expand("<cword>")
|
local search = opts.search or vim.fn.expand("<cword>")
|
||||||
|
|
||||||
local grepper = finders.new {
|
local file_picker = pickers.new(opts, {
|
||||||
maximum_results = 10000,
|
prompt = 'Find Word',
|
||||||
|
finder = finders.new_oneshot_job {'rg', '--vimgrep', search},
|
||||||
-- TODO: We can optimize these.
|
previewer = previewers.vimgrep,
|
||||||
-- static = true,
|
|
||||||
|
|
||||||
fn_command = function()
|
|
||||||
return {
|
|
||||||
command = 'rg',
|
|
||||||
args = {"--vimgrep", search},
|
|
||||||
}
|
|
||||||
end
|
|
||||||
}
|
|
||||||
|
|
||||||
local file_picker = pickers.new {
|
|
||||||
previewer = previewers.vimgrep
|
|
||||||
}
|
|
||||||
|
|
||||||
file_picker:find {
|
|
||||||
prompt = 'Live Grep',
|
|
||||||
finder = grepper,
|
|
||||||
sorter = sorters.get_norcalli_sorter(),
|
sorter = sorters.get_norcalli_sorter(),
|
||||||
}
|
}):find()
|
||||||
end
|
end
|
||||||
|
|
||||||
builtin.oldfiles = function()
|
builtin.oldfiles = function(opts)
|
||||||
local oldfiles_finder = finders.new {
|
pickers.new(opts, {
|
||||||
results = vim.v.oldfiles
|
|
||||||
}
|
|
||||||
local file_picker = pickers.new{}
|
|
||||||
|
|
||||||
file_picker:find {
|
|
||||||
prompt = 'Oldfiles',
|
prompt = 'Oldfiles',
|
||||||
finder = oldfiles_finder,
|
finder = finders.new_table(vim.tbl_filter(function(val)
|
||||||
sorter = sorters.get_norcalli_sorter()
|
return 0 ~= vim.fn.filereadable(val)
|
||||||
}
|
end, vim.v.oldfiles)),
|
||||||
|
sorter = sorters.get_norcalli_sorter(),
|
||||||
|
previewer = previewers.cat,
|
||||||
|
}):find()
|
||||||
end
|
end
|
||||||
|
|
||||||
return builtin
|
return builtin
|
||||||
|
|||||||
@@ -1,17 +1,19 @@
|
|||||||
local Job = require('plenary.job')
|
local Job = require('plenary.job')
|
||||||
|
|
||||||
local log = require('telescope.log')
|
local log = require('telescope.log')
|
||||||
|
local utils = require('telescope.utils')
|
||||||
|
|
||||||
local finders = {}
|
local finders = {}
|
||||||
|
|
||||||
|
|
||||||
-- TODO: We should make a few different "FinderGenerators":
|
-- TODO: We should make a few different "FinderGenerators":
|
||||||
-- SimpleListFinder(my_list)
|
-- SimpleListFinder(my_list)
|
||||||
-- FunctionFinder(my_func)
|
-- FunctionFinder(my_func)
|
||||||
-- JobFinder(my_job_args)
|
-- JobFinder(my_job_args)
|
||||||
|
|
||||||
---@class Finder
|
---@class Finder
|
||||||
local Finder = {}
|
local Finder = {
|
||||||
|
hello = "world"
|
||||||
|
}
|
||||||
|
|
||||||
Finder.__index = Finder
|
Finder.__index = Finder
|
||||||
Finder.__call = function(t, ... ) return t:_find(...) end
|
Finder.__call = function(t, ... ) return t:_find(...) end
|
||||||
@@ -35,7 +37,7 @@ function Finder:new(opts)
|
|||||||
-- string
|
-- string
|
||||||
-- list
|
-- list
|
||||||
-- ...
|
-- ...
|
||||||
return setmetatable({
|
local obj = setmetatable({
|
||||||
results = opts.results,
|
results = opts.results,
|
||||||
|
|
||||||
fn_command = opts.fn_command,
|
fn_command = opts.fn_command,
|
||||||
@@ -45,7 +47,9 @@ function Finder:new(opts)
|
|||||||
-- Maximum number of results to process.
|
-- Maximum number of results to process.
|
||||||
-- Particularly useful for live updating large queries.
|
-- Particularly useful for live updating large queries.
|
||||||
maximum_results = opts.maximum_results,
|
maximum_results = opts.maximum_results,
|
||||||
}, Finder)
|
}, self)
|
||||||
|
|
||||||
|
return obj
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Probably should use the word apply here, since we're apply the callback passed to us by
|
-- Probably should use the word apply here, since we're apply the callback passed to us by
|
||||||
@@ -145,8 +149,38 @@ end
|
|||||||
--- Return a new Finder
|
--- Return a new Finder
|
||||||
--
|
--
|
||||||
--@return Finder
|
--@return Finder
|
||||||
finders.new = function(...)
|
finders.new = function(opts)
|
||||||
return Finder:new(...)
|
return Finder:new(opts)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- TODO: Is this worth making?
|
||||||
|
-- finders.new_responsive_job = function(opts)
|
||||||
|
-- return finders.new {
|
||||||
|
-- maximum_results = get_default(opts.maximum_results, 2000),
|
||||||
|
-- }
|
||||||
|
-- end
|
||||||
|
|
||||||
|
finders.new_oneshot_job = function(command_list)
|
||||||
|
command_list = vim.deepcopy(command_list)
|
||||||
|
|
||||||
|
local command = table.remove(command_list, 1)
|
||||||
|
|
||||||
|
return finders.new {
|
||||||
|
static = true,
|
||||||
|
|
||||||
|
fn_command = function()
|
||||||
|
return {
|
||||||
|
command = command,
|
||||||
|
args = command_list,
|
||||||
|
}
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
finders.new_table = function(t)
|
||||||
|
return finders.new {
|
||||||
|
results = t
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
-- We should add a few utility functions here...
|
-- We should add a few utility functions here...
|
||||||
@@ -155,6 +189,6 @@ end
|
|||||||
-- finders.new_one_shot_job
|
-- finders.new_one_shot_job
|
||||||
-- finders.new_table
|
-- finders.new_table
|
||||||
|
|
||||||
finders.Finder = Finder
|
-- finders.Finder = Finder
|
||||||
|
|
||||||
return finders
|
return finders
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
local a = vim.api
|
local a = vim.api
|
||||||
local popup = require('popup')
|
local popup = require('popup')
|
||||||
|
local has_devicons, devicons = pcall(require, 'nvim-web-devicons')
|
||||||
|
|
||||||
local actions = require('telescope.actions')
|
local actions = require('telescope.actions')
|
||||||
local log = require('telescope.log')
|
local log = require('telescope.log')
|
||||||
@@ -8,15 +9,23 @@ local state = require('telescope.state')
|
|||||||
local utils = require('telescope.utils')
|
local utils = require('telescope.utils')
|
||||||
|
|
||||||
local Entry = require('telescope.entry')
|
local Entry = require('telescope.entry')
|
||||||
local Sorter = require('telescope.sorters').Sorter
|
|
||||||
local Previewer = require('telescope.previewers').Previewer
|
|
||||||
|
|
||||||
local has_devicons, devicons = pcall(require, 'nvim-web-devicons')
|
local get_default = utils.get_default
|
||||||
|
|
||||||
|
-- TODO: Make this work with deep extend I think.
|
||||||
|
local extend = function(opts, defaults)
|
||||||
|
local result = vim.deepcopy(opts or {})
|
||||||
|
for k, v in pairs(defaults or {}) do
|
||||||
|
if result[k] == nil then
|
||||||
|
result[k] = v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
local pickers = {}
|
local pickers = {}
|
||||||
|
|
||||||
local ifnil = function(x, was_nil, was_not_nil) if x == nil then return was_nil else return was_not_nil end end
|
|
||||||
|
|
||||||
local default_mappings = {
|
local default_mappings = {
|
||||||
i = {
|
i = {
|
||||||
["<C-n>"] = actions.move_selection_next,
|
["<C-n>"] = actions.move_selection_next,
|
||||||
@@ -42,58 +51,60 @@ local default_mappings = {
|
|||||||
local Picker = {}
|
local Picker = {}
|
||||||
Picker.__index = Picker
|
Picker.__index = Picker
|
||||||
|
|
||||||
assert(Sorter)
|
|
||||||
assert(Previewer)
|
|
||||||
|
|
||||||
---@class PickOpts
|
|
||||||
---@field filter Sorter
|
|
||||||
---@field maps table
|
|
||||||
---@field unseen string
|
|
||||||
|
|
||||||
--- Create new picker
|
--- Create new picker
|
||||||
--- @param opts PickOpts
|
|
||||||
function Picker:new(opts)
|
function Picker:new(opts)
|
||||||
opts = opts or {}
|
opts = opts or {}
|
||||||
|
|
||||||
return setmetatable({
|
return setmetatable({
|
||||||
filter = opts.filter,
|
prompt = opts.prompt,
|
||||||
|
|
||||||
|
finder = opts.finder,
|
||||||
|
sorter = opts.sorter,
|
||||||
previewer = opts.previewer,
|
previewer = opts.previewer,
|
||||||
maps = opts.maps,
|
|
||||||
|
mappings = get_default(opts.mappings, default_mappings),
|
||||||
|
|
||||||
get_window_options = opts.get_window_options,
|
get_window_options = opts.get_window_options,
|
||||||
|
|
||||||
selection_strategy = opts.selection_strategy,
|
selection_strategy = opts.selection_strategy,
|
||||||
|
|
||||||
|
window = {
|
||||||
|
border = get_default(opts.border, {}),
|
||||||
|
borderchars = get_default(opts.borderchars, { '─', '│', '─', '│', '┌', '┐', '┘', '└'}),
|
||||||
|
},
|
||||||
|
|
||||||
|
preview_cutoff = get_default(opts.preview_cutoff, 120),
|
||||||
}, Picker)
|
}, Picker)
|
||||||
end
|
end
|
||||||
|
|
||||||
function Picker:get_window_options(max_columns, max_lines, prompt_title, find_options)
|
function Picker:get_window_options(max_columns, max_lines, prompt_title)
|
||||||
|
local popup_border = self.window.border
|
||||||
local popup_border = ifnil(find_options.border, {}, find_options.border)
|
local popup_borderchars = self.window.borderchars
|
||||||
|
|
||||||
local preview = {
|
local preview = {
|
||||||
border = popup_border,
|
border = popup_border,
|
||||||
borderchars = find_options.borderchars or nil,
|
borderchars = popup_borderchars,
|
||||||
enter = false,
|
enter = false,
|
||||||
highlight = false
|
highlight = false
|
||||||
}
|
}
|
||||||
|
|
||||||
local results = {
|
local results = {
|
||||||
border = popup_border,
|
border = popup_border,
|
||||||
borderchars = find_options.borderchars or nil,
|
borderchars = popup_borderchars,
|
||||||
enter = false,
|
enter = false,
|
||||||
}
|
}
|
||||||
|
|
||||||
local prompt = {
|
local prompt = {
|
||||||
title = prompt_title,
|
title = prompt_title,
|
||||||
border = popup_border,
|
border = popup_border,
|
||||||
borderchars = find_options.borderchars or nil,
|
borderchars = popup_borderchars,
|
||||||
enter = true
|
enter = true
|
||||||
}
|
}
|
||||||
|
|
||||||
-- TODO: Test with 120 width terminal
|
-- TODO: Test with 120 width terminal
|
||||||
|
|
||||||
local width_padding = 10
|
local width_padding = 10
|
||||||
if not self.previewer or max_columns < find_options.preview_cutoff then
|
if not self.previewer or max_columns < self.preview_cutoff then
|
||||||
|
width_padding = 2
|
||||||
preview.width = 0
|
preview.width = 0
|
||||||
elseif max_columns < 150 then
|
elseif max_columns < 150 then
|
||||||
width_padding = 5
|
width_padding = 5
|
||||||
@@ -110,7 +121,7 @@ function Picker:get_window_options(max_columns, max_lines, prompt_title, find_op
|
|||||||
|
|
||||||
local base_height
|
local base_height
|
||||||
if max_lines < 40 then
|
if max_lines < 40 then
|
||||||
base_height = math.floor(max_lines * 0.5)
|
base_height = math.min(math.floor(max_lines * 0.8), max_lines - 8)
|
||||||
else
|
else
|
||||||
base_height = math.floor(max_lines * 0.8)
|
base_height = math.floor(max_lines * 0.8)
|
||||||
end
|
end
|
||||||
@@ -143,21 +154,10 @@ function Picker:get_window_options(max_columns, max_lines, prompt_title, find_op
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
-- opts.preview_cutoff = 120
|
function Picker:find()
|
||||||
function Picker:find(opts)
|
local prompt_string = assert(self.prompt, "Prompt is required.")
|
||||||
opts = opts or {}
|
local finder = assert(self.finder, "Finder is required to do picking")
|
||||||
|
local sorter = self.sorter
|
||||||
if opts.preview_cutoff == nil then
|
|
||||||
opts.preview_cutoff = 120
|
|
||||||
end
|
|
||||||
|
|
||||||
opts.borderchars = opts.borderchars or { '─', '│', '─', '│', '┌', '┐', '┘', '└'}
|
|
||||||
|
|
||||||
local finder = opts.finder
|
|
||||||
assert(finder, "Finder is required to do picking")
|
|
||||||
|
|
||||||
local sorter = opts.sorter
|
|
||||||
local prompt_string = opts.prompt
|
|
||||||
|
|
||||||
self.original_win_id = a.nvim_get_current_win()
|
self.original_win_id = a.nvim_get_current_win()
|
||||||
|
|
||||||
@@ -165,7 +165,7 @@ function Picker:find(opts)
|
|||||||
-- 1. Prompt window
|
-- 1. Prompt window
|
||||||
-- 2. Options window
|
-- 2. Options window
|
||||||
-- 3. Preview window
|
-- 3. Preview window
|
||||||
local popup_opts = self:get_window_options(vim.o.columns, vim.o.lines, prompt_string, opts)
|
local popup_opts = self:get_window_options(vim.o.columns, vim.o.lines, prompt_string)
|
||||||
|
|
||||||
-- TODO: Add back the borders after fixing some stuff in popup.nvim
|
-- TODO: Add back the borders after fixing some stuff in popup.nvim
|
||||||
local results_win, results_opts = popup.create('', popup_opts.results)
|
local results_win, results_opts = popup.create('', popup_opts.results)
|
||||||
@@ -338,8 +338,7 @@ function Picker:find(opts)
|
|||||||
finder = finder,
|
finder = finder,
|
||||||
})
|
})
|
||||||
|
|
||||||
-- mappings.set_keymap(prompt_bufnr, results_bufnr)
|
mappings.apply_keymap(prompt_bufnr, self.mappings)
|
||||||
mappings.apply_keymap(prompt_bufnr, opts.mappings or default_mappings)
|
|
||||||
|
|
||||||
vim.cmd [[startinsert]]
|
vim.cmd [[startinsert]]
|
||||||
end
|
end
|
||||||
@@ -462,8 +461,9 @@ function Picker:set_selection(row)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
pickers.new = function(...)
|
pickers.new = function(opts, defaults)
|
||||||
return Picker:new(...)
|
opts = extend(opts, defaults)
|
||||||
|
return Picker:new(opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- TODO: We should consider adding `process_bulk` or `bulk_entry_manager` for things
|
-- TODO: We should consider adding `process_bulk` or `bulk_entry_manager` for things
|
||||||
|
|||||||
@@ -1,5 +1,25 @@
|
|||||||
local utils = {}
|
local utils = {}
|
||||||
|
|
||||||
|
utils.if_nil = function(x, was_nil, was_not_nil)
|
||||||
|
if x == nil then
|
||||||
|
return was_nil
|
||||||
|
else
|
||||||
|
return was_not_nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
utils.get_default = function(x, default)
|
||||||
|
return utils.if_nil(x, default, x)
|
||||||
|
end
|
||||||
|
|
||||||
|
utils.get_lazy_default = function(x, defaulter, ...)
|
||||||
|
if x == nil then
|
||||||
|
return defaulter(...)
|
||||||
|
else
|
||||||
|
return x
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local function reversedipairsiter(t, i)
|
local function reversedipairsiter(t, i)
|
||||||
i = i - 1
|
i = i - 1
|
||||||
if i ~= 0 then
|
if i ~= 0 then
|
||||||
@@ -27,119 +47,31 @@ utils.repeated_table = function(n, val)
|
|||||||
return empty_lines
|
return empty_lines
|
||||||
end
|
end
|
||||||
|
|
||||||
|
utils.quickfix_items_to_entries = function(locations)
|
||||||
local NGram = {}
|
|
||||||
NGram.__index = NGram
|
|
||||||
|
|
||||||
function NGram:new(opts)
|
|
||||||
-- TODO: Add padding
|
|
||||||
opts = opts or {}
|
|
||||||
return setmetatable({
|
|
||||||
N = opts.N or 2,
|
|
||||||
split = opts.split or "/",
|
|
||||||
_depth = 5,
|
|
||||||
_grams = setmetatable({}, utils.default_table_mt)
|
|
||||||
}, self)
|
|
||||||
end
|
|
||||||
|
|
||||||
local min = math.min
|
|
||||||
|
|
||||||
function NGram:_split(word)
|
|
||||||
local word_len = #word
|
|
||||||
|
|
||||||
local result = {}
|
|
||||||
for i = 1, word_len - 1 do
|
|
||||||
-- for j = i + (self.N - 1), min(i + self._depth - 1, word_len) do
|
|
||||||
-- table.insert(result, string.sub(word, i, j))
|
|
||||||
-- end
|
|
||||||
table.insert(result, string.sub(word, i, i + self.N - 1))
|
|
||||||
end
|
|
||||||
|
|
||||||
return result
|
|
||||||
end
|
|
||||||
|
|
||||||
-- local function pairsByKeys (t, f)
|
|
||||||
-- local a = {}
|
|
||||||
-- for n in pairs(t) do table.insert(a, n) end
|
|
||||||
-- table.sort(a, f)
|
|
||||||
-- local i = 0 -- iterator variable
|
|
||||||
-- local iter = function () -- iterator function
|
|
||||||
-- i = i + 1
|
|
||||||
-- if a[i] == nil then return nil
|
|
||||||
-- else return a[i], t[a[i]]
|
|
||||||
-- end
|
|
||||||
-- end
|
|
||||||
-- return iter
|
|
||||||
-- end
|
|
||||||
|
|
||||||
function NGram:add(word)
|
|
||||||
local split_word = self:_split(word)
|
|
||||||
|
|
||||||
for _, k in ipairs(split_word) do
|
|
||||||
local counts = self._grams[k]
|
|
||||||
if counts[word] == nil then
|
|
||||||
counts[word] = 0
|
|
||||||
end
|
|
||||||
|
|
||||||
counts[word] = counts[word] + 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function NGram:_items_sharing_ngrams(query)
|
|
||||||
local split_query = self:_split(query)
|
|
||||||
|
|
||||||
-- Matched string to number of N-grams shared with the query string.
|
|
||||||
local shared = {}
|
|
||||||
|
|
||||||
local remaining = {}
|
|
||||||
|
|
||||||
for _, ngram in ipairs(split_query) do
|
|
||||||
remaining = {}
|
|
||||||
for match, count in pairs(self._grams[ngram] or {}) do
|
|
||||||
remaining[match] = remaining[match] or count
|
|
||||||
|
|
||||||
if remaining[match] > 0 then
|
|
||||||
remaining[match] = remaining[match] - 1
|
|
||||||
shared[match] = (shared[match] or 0) + 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return shared
|
|
||||||
end
|
|
||||||
|
|
||||||
function NGram:search(query, show_values)
|
|
||||||
local sharing_ngrams = self:_items_sharing_ngrams(query)
|
|
||||||
|
|
||||||
local results = {}
|
local results = {}
|
||||||
for name, count in pairs(sharing_ngrams) do
|
|
||||||
local allgrams = #query + #name - (2 * self.N) - count + 2
|
|
||||||
table.insert(results, {name, count / allgrams})
|
|
||||||
end
|
|
||||||
|
|
||||||
table.sort(results, function(left, right)
|
for _, entry in ipairs(locations) do
|
||||||
return left[2] > right[2]
|
local vimgrep_str = string.format(
|
||||||
end)
|
"%s:%s:%s: %s",
|
||||||
|
vim.fn.fnamemodify(entry.filename, ":."),
|
||||||
|
entry.lnum,
|
||||||
|
entry.col,
|
||||||
|
entry.text
|
||||||
|
)
|
||||||
|
|
||||||
if not show_values then
|
table.insert(results, {
|
||||||
for k, v in ipairs(results) do
|
valid = true,
|
||||||
results[k] = v[1]
|
value = entry,
|
||||||
end
|
ordinal = vimgrep_str,
|
||||||
|
display = vimgrep_str,
|
||||||
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
return results
|
return results
|
||||||
end
|
end
|
||||||
|
|
||||||
function NGram:find(query)
|
|
||||||
return self:search(query)[1]
|
|
||||||
end
|
|
||||||
|
|
||||||
function NGram:score(query)
|
|
||||||
return (self:search(query, true)[1] or {})[2] or 0
|
|
||||||
end
|
|
||||||
|
|
||||||
utils.new_ngram = function()
|
utils.new_ngram = function()
|
||||||
return NGram:new()
|
return require("telescope._private.NGram"):new()
|
||||||
end
|
end
|
||||||
|
|
||||||
return utils
|
return utils
|
||||||
|
|||||||
24
scratch/rocker_example.lua
Normal file
24
scratch/rocker_example.lua
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
|
||||||
|
|
||||||
|
builtin.git_files = function(opts)
|
||||||
|
opts = opts or {}
|
||||||
|
|
||||||
|
opts.show_preview = get_default(opts.show_preview, true)
|
||||||
|
|
||||||
|
opts.finder = opts.finder or finders.new {
|
||||||
|
static = true,
|
||||||
|
|
||||||
|
fn_command = function()
|
||||||
|
return {
|
||||||
|
command = 'git',
|
||||||
|
args = {'ls-files'}
|
||||||
|
}
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
opts.prompt = opts.prompt or 'Simple File'
|
||||||
|
opts.previewer = opts.previewer or previewers.cat
|
||||||
|
opts.sorter = opts.sorter or sorters.get_norcalli_sorter()
|
||||||
|
|
||||||
|
pickers.new(opts):find()
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user