mirror of
https://github.com/zoriya/telescope.nvim.git
synced 2025-12-06 06:46:10 +00:00
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 pickers = require('telescope.pickers')
|
||||
local sorters = require('telescope.sorters')
|
||||
local utils = require('telescope.utils')
|
||||
|
||||
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)
|
||||
opts = opts or {}
|
||||
|
||||
local show_preview = ifnil(opts.show_preview, true, opts.show_preview)
|
||||
|
||||
local file_finder = finders.new {
|
||||
static = true,
|
||||
|
||||
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,
|
||||
}
|
||||
pickers.new(opts, {
|
||||
prompt = 'Git File',
|
||||
finder = finders.new_oneshot_job({ "git", "ls-files" }),
|
||||
previewer = previewers.cat,
|
||||
sorter = sorters.get_norcalli_sorter(),
|
||||
}):find()
|
||||
end
|
||||
|
||||
builtin.live_grep = function()
|
||||
builtin.live_grep = function(opts)
|
||||
local live_grepper = finders.new {
|
||||
maximum_results = 1000,
|
||||
|
||||
@@ -68,15 +38,13 @@ builtin.live_grep = function()
|
||||
end
|
||||
}
|
||||
|
||||
local file_previewer = previewers.vimgrep
|
||||
local file_picker = pickers.new {
|
||||
previewer = file_previewer
|
||||
}
|
||||
|
||||
-- local file_sorter = telescope.sorters.get_ngram_sorter()
|
||||
-- local file_sorter = require('telescope.sorters').get_levenshtein_sorter()
|
||||
-- local file_sorter = sorters.get_norcalli_sorter()
|
||||
pickers.new(opts, {
|
||||
prompt = 'Live Grep',
|
||||
finder = live_grepper,
|
||||
previewer = previewers.vimgrep,
|
||||
}):find()
|
||||
|
||||
-- TODO: Incorporate this.
|
||||
-- Weight the results somehow to be more likely to be the ones that you've opened.
|
||||
-- local old_files = {}
|
||||
-- for _, f in ipairs(vim.v.oldfiles) do
|
||||
@@ -102,15 +70,9 @@ builtin.live_grep = function()
|
||||
-- end
|
||||
-- end
|
||||
-- }
|
||||
|
||||
file_picker:find {
|
||||
prompt = 'Live Grep',
|
||||
finder = live_grepper,
|
||||
sorter = oldfiles_sorter,
|
||||
}
|
||||
end
|
||||
|
||||
builtin.lsp_references = function()
|
||||
builtin.lsp_references = function(opts)
|
||||
local params = vim.lsp.util.make_position_params()
|
||||
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 {})
|
||||
end
|
||||
|
||||
local results = {}
|
||||
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
|
||||
local results = utils.quickfix_items_to_entries(locations)
|
||||
|
||||
if vim.tbl_isempty(results) then
|
||||
return
|
||||
end
|
||||
|
||||
local lsp_reference_finder = finders.new {
|
||||
results = results
|
||||
}
|
||||
|
||||
local reference_previewer = previewers.qflist
|
||||
local reference_picker = pickers.new {
|
||||
previewer = reference_previewer
|
||||
}
|
||||
|
||||
reference_picker:find {
|
||||
prompt = 'LSP References',
|
||||
finder = lsp_reference_finder,
|
||||
sorter = sorters.get_norcalli_sorter(),
|
||||
}
|
||||
local reference_picker = pickers.new(opts, {
|
||||
prompt = 'LSP References',
|
||||
finder = finders.new_table(results),
|
||||
previewer = previewers.qflist,
|
||||
sorter = sorters.get_norcalli_sorter(),
|
||||
}):find()
|
||||
end
|
||||
|
||||
builtin.quickfix = function()
|
||||
builtin.quickfix = function(opts)
|
||||
local locations = vim.fn.getqflist()
|
||||
|
||||
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
|
||||
local results = utils.quickfix_items_to_entries(locations)
|
||||
|
||||
if vim.tbl_isempty(results) then
|
||||
return
|
||||
end
|
||||
|
||||
local quickfix_finder = finders.new {
|
||||
results = results
|
||||
}
|
||||
|
||||
local quickfix_previewer = previewers.qflist
|
||||
local quickfix_picker = pickers.new {
|
||||
previewer = quickfix_previewer
|
||||
}
|
||||
|
||||
quickfix_picker:find {
|
||||
prompt = 'Quickfix',
|
||||
finder = quickfix_finder,
|
||||
sorter = sorters.get_norcalli_sorter(),
|
||||
}
|
||||
pickers.new(opts, {
|
||||
prompt = 'Quickfix',
|
||||
finder = finders.new_table(results),
|
||||
previewer = previewers.qflist,
|
||||
sorter = sorters.get_norcalli_sorter(),
|
||||
}):find()
|
||||
end
|
||||
|
||||
builtin.grep_string = function(opts)
|
||||
@@ -208,42 +117,23 @@ builtin.grep_string = function(opts)
|
||||
|
||||
local search = opts.search or vim.fn.expand("<cword>")
|
||||
|
||||
local grepper = finders.new {
|
||||
maximum_results = 10000,
|
||||
|
||||
-- TODO: We can optimize these.
|
||||
-- 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,
|
||||
local file_picker = pickers.new(opts, {
|
||||
prompt = 'Find Word',
|
||||
finder = finders.new_oneshot_job {'rg', '--vimgrep', search},
|
||||
previewer = previewers.vimgrep,
|
||||
sorter = sorters.get_norcalli_sorter(),
|
||||
}
|
||||
}):find()
|
||||
end
|
||||
|
||||
builtin.oldfiles = function()
|
||||
local oldfiles_finder = finders.new {
|
||||
results = vim.v.oldfiles
|
||||
}
|
||||
local file_picker = pickers.new{}
|
||||
|
||||
file_picker:find {
|
||||
builtin.oldfiles = function(opts)
|
||||
pickers.new(opts, {
|
||||
prompt = 'Oldfiles',
|
||||
finder = oldfiles_finder,
|
||||
sorter = sorters.get_norcalli_sorter()
|
||||
}
|
||||
finder = finders.new_table(vim.tbl_filter(function(val)
|
||||
return 0 ~= vim.fn.filereadable(val)
|
||||
end, vim.v.oldfiles)),
|
||||
sorter = sorters.get_norcalli_sorter(),
|
||||
previewer = previewers.cat,
|
||||
}):find()
|
||||
end
|
||||
|
||||
return builtin
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
local Job = require('plenary.job')
|
||||
|
||||
local log = require('telescope.log')
|
||||
local utils = require('telescope.utils')
|
||||
|
||||
local finders = {}
|
||||
|
||||
|
||||
-- TODO: We should make a few different "FinderGenerators":
|
||||
-- SimpleListFinder(my_list)
|
||||
-- FunctionFinder(my_func)
|
||||
-- JobFinder(my_job_args)
|
||||
|
||||
---@class Finder
|
||||
local Finder = {}
|
||||
local Finder = {
|
||||
hello = "world"
|
||||
}
|
||||
|
||||
Finder.__index = Finder
|
||||
Finder.__call = function(t, ... ) return t:_find(...) end
|
||||
@@ -35,7 +37,7 @@ function Finder:new(opts)
|
||||
-- string
|
||||
-- list
|
||||
-- ...
|
||||
return setmetatable({
|
||||
local obj = setmetatable({
|
||||
results = opts.results,
|
||||
|
||||
fn_command = opts.fn_command,
|
||||
@@ -45,7 +47,9 @@ function Finder:new(opts)
|
||||
-- Maximum number of results to process.
|
||||
-- Particularly useful for live updating large queries.
|
||||
maximum_results = opts.maximum_results,
|
||||
}, Finder)
|
||||
}, self)
|
||||
|
||||
return obj
|
||||
end
|
||||
|
||||
-- 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 Finder
|
||||
finders.new = function(...)
|
||||
return Finder:new(...)
|
||||
finders.new = function(opts)
|
||||
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
|
||||
|
||||
-- We should add a few utility functions here...
|
||||
@@ -155,6 +189,6 @@ end
|
||||
-- finders.new_one_shot_job
|
||||
-- finders.new_table
|
||||
|
||||
finders.Finder = Finder
|
||||
-- finders.Finder = Finder
|
||||
|
||||
return finders
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
local a = vim.api
|
||||
local popup = require('popup')
|
||||
local has_devicons, devicons = pcall(require, 'nvim-web-devicons')
|
||||
|
||||
local actions = require('telescope.actions')
|
||||
local log = require('telescope.log')
|
||||
@@ -8,15 +9,23 @@ local state = require('telescope.state')
|
||||
local utils = require('telescope.utils')
|
||||
|
||||
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 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 = {
|
||||
i = {
|
||||
["<C-n>"] = actions.move_selection_next,
|
||||
@@ -42,58 +51,60 @@ local default_mappings = {
|
||||
local Picker = {}
|
||||
Picker.__index = Picker
|
||||
|
||||
assert(Sorter)
|
||||
assert(Previewer)
|
||||
|
||||
---@class PickOpts
|
||||
---@field filter Sorter
|
||||
---@field maps table
|
||||
---@field unseen string
|
||||
|
||||
--- Create new picker
|
||||
--- @param opts PickOpts
|
||||
function Picker:new(opts)
|
||||
opts = opts or {}
|
||||
|
||||
return setmetatable({
|
||||
filter = opts.filter,
|
||||
prompt = opts.prompt,
|
||||
|
||||
finder = opts.finder,
|
||||
sorter = opts.sorter,
|
||||
previewer = opts.previewer,
|
||||
maps = opts.maps,
|
||||
|
||||
mappings = get_default(opts.mappings, default_mappings),
|
||||
|
||||
get_window_options = opts.get_window_options,
|
||||
|
||||
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)
|
||||
end
|
||||
|
||||
function Picker:get_window_options(max_columns, max_lines, prompt_title, find_options)
|
||||
|
||||
local popup_border = ifnil(find_options.border, {}, find_options.border)
|
||||
function Picker:get_window_options(max_columns, max_lines, prompt_title)
|
||||
local popup_border = self.window.border
|
||||
local popup_borderchars = self.window.borderchars
|
||||
|
||||
local preview = {
|
||||
border = popup_border,
|
||||
borderchars = find_options.borderchars or nil,
|
||||
borderchars = popup_borderchars,
|
||||
enter = false,
|
||||
highlight = false
|
||||
}
|
||||
|
||||
local results = {
|
||||
border = popup_border,
|
||||
borderchars = find_options.borderchars or nil,
|
||||
borderchars = popup_borderchars,
|
||||
enter = false,
|
||||
}
|
||||
|
||||
local prompt = {
|
||||
title = prompt_title,
|
||||
border = popup_border,
|
||||
borderchars = find_options.borderchars or nil,
|
||||
borderchars = popup_borderchars,
|
||||
enter = true
|
||||
}
|
||||
|
||||
-- TODO: Test with 120 width terminal
|
||||
|
||||
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
|
||||
elseif max_columns < 150 then
|
||||
width_padding = 5
|
||||
@@ -110,7 +121,7 @@ function Picker:get_window_options(max_columns, max_lines, prompt_title, find_op
|
||||
|
||||
local base_height
|
||||
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
|
||||
base_height = math.floor(max_lines * 0.8)
|
||||
end
|
||||
@@ -143,21 +154,10 @@ function Picker:get_window_options(max_columns, max_lines, prompt_title, find_op
|
||||
}
|
||||
end
|
||||
|
||||
-- opts.preview_cutoff = 120
|
||||
function Picker:find(opts)
|
||||
opts = opts or {}
|
||||
|
||||
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
|
||||
function Picker:find()
|
||||
local prompt_string = assert(self.prompt, "Prompt is required.")
|
||||
local finder = assert(self.finder, "Finder is required to do picking")
|
||||
local sorter = self.sorter
|
||||
|
||||
self.original_win_id = a.nvim_get_current_win()
|
||||
|
||||
@@ -165,7 +165,7 @@ function Picker:find(opts)
|
||||
-- 1. Prompt window
|
||||
-- 2. Options 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
|
||||
local results_win, results_opts = popup.create('', popup_opts.results)
|
||||
@@ -338,8 +338,7 @@ function Picker:find(opts)
|
||||
finder = finder,
|
||||
})
|
||||
|
||||
-- mappings.set_keymap(prompt_bufnr, results_bufnr)
|
||||
mappings.apply_keymap(prompt_bufnr, opts.mappings or default_mappings)
|
||||
mappings.apply_keymap(prompt_bufnr, self.mappings)
|
||||
|
||||
vim.cmd [[startinsert]]
|
||||
end
|
||||
@@ -462,8 +461,9 @@ function Picker:set_selection(row)
|
||||
end
|
||||
end
|
||||
|
||||
pickers.new = function(...)
|
||||
return Picker:new(...)
|
||||
pickers.new = function(opts, defaults)
|
||||
opts = extend(opts, defaults)
|
||||
return Picker:new(opts)
|
||||
end
|
||||
|
||||
-- TODO: We should consider adding `process_bulk` or `bulk_entry_manager` for things
|
||||
|
||||
@@ -1,5 +1,25 @@
|
||||
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)
|
||||
i = i - 1
|
||||
if i ~= 0 then
|
||||
@@ -27,119 +47,31 @@ utils.repeated_table = function(n, val)
|
||||
return empty_lines
|
||||
end
|
||||
|
||||
|
||||
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)
|
||||
|
||||
utils.quickfix_items_to_entries = function(locations)
|
||||
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)
|
||||
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
|
||||
)
|
||||
|
||||
if not show_values then
|
||||
for k, v in ipairs(results) do
|
||||
results[k] = v[1]
|
||||
end
|
||||
table.insert(results, {
|
||||
valid = true,
|
||||
value = entry,
|
||||
ordinal = vimgrep_str,
|
||||
display = vimgrep_str,
|
||||
})
|
||||
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
|
||||
|
||||
utils.new_ngram = function()
|
||||
return NGram:new()
|
||||
return require("telescope._private.NGram"):new()
|
||||
end
|
||||
|
||||
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