feat: Major improvements in API. Particularly relating to entries.
This commit is contained in:
@@ -42,22 +42,31 @@ function actions.goto_file_selection(prompt_bufnr)
|
|||||||
print("[telescope] Nothing currently selected")
|
print("[telescope] Nothing currently selected")
|
||||||
return
|
return
|
||||||
else
|
else
|
||||||
|
local filename, row, col
|
||||||
|
if entry.filename then
|
||||||
|
filename = entry.filename
|
||||||
|
-- TODO: Check for off-by-one
|
||||||
|
row = entry.row or entry.lnum
|
||||||
|
col = entry.col
|
||||||
|
else
|
||||||
|
-- TODO: Might want to remove this and force people
|
||||||
|
-- to put stuff into `filename`
|
||||||
local value = entry.value
|
local value = entry.value
|
||||||
if not value then
|
if not value then
|
||||||
print("Could not do anything with blank line...")
|
print("Could not do anything with blank line...")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- TODO: This is not great.
|
|
||||||
if type(value) == "table" then
|
if type(value) == "table" then
|
||||||
value = entry.display
|
value = entry.display
|
||||||
end
|
end
|
||||||
|
|
||||||
local sections = vim.split(value, ":")
|
local sections = vim.split(value, ":")
|
||||||
|
|
||||||
local filename = sections[1]
|
filename = sections[1]
|
||||||
local row = tonumber(sections[2])
|
row = tonumber(sections[2])
|
||||||
local col = tonumber(sections[3])
|
col = tonumber(sections[3])
|
||||||
|
end
|
||||||
|
|
||||||
vim.cmd(string.format([[bwipeout! %s]], prompt_bufnr))
|
vim.cmd(string.format([[bwipeout! %s]], prompt_bufnr))
|
||||||
|
|
||||||
|
|||||||
@@ -11,94 +11,69 @@ This will use the default configuration options.
|
|||||||
Other configuration options still in flux at the moment
|
Other configuration options still in flux at the moment
|
||||||
--]]
|
--]]
|
||||||
|
|
||||||
|
-- TODO: Give some bonus weight to files we've picked before
|
||||||
|
-- TODO: Give some bonus weight to oldfiles
|
||||||
|
|
||||||
local actions = require('telescope.actions')
|
local actions = require('telescope.actions')
|
||||||
local finders = require('telescope.finders')
|
local finders = require('telescope.finders')
|
||||||
|
local make_entry = require('telescope.make_entry')
|
||||||
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 utils = require('telescope.utils')
|
||||||
|
|
||||||
|
local flatten = vim.tbl_flatten
|
||||||
|
|
||||||
|
-- TODO: Support silver search here.
|
||||||
|
-- TODO: Support normal grep here (in case neither are installed).
|
||||||
|
local vimgrep_arguments = {'rg', '--color=never', '--no-heading', '--with-filename', '--line-number', '--column'}
|
||||||
|
|
||||||
local builtin = {}
|
local builtin = {}
|
||||||
|
|
||||||
builtin.git_files = function(opts)
|
builtin.git_files = function(opts)
|
||||||
opts = opts or {}
|
opts = opts or {}
|
||||||
|
|
||||||
local make_entry = (
|
|
||||||
opts.shorten_path
|
|
||||||
and function(value)
|
|
||||||
local result = {
|
|
||||||
valid = true,
|
|
||||||
display = utils.path_shorten(value),
|
|
||||||
ordinal = value,
|
|
||||||
value = value
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
end)
|
|
||||||
|
|
||||||
or nil
|
|
||||||
|
|
||||||
pickers.new(opts, {
|
pickers.new(opts, {
|
||||||
prompt = 'Git File',
|
prompt = 'Git File',
|
||||||
finder = finders.new_oneshot_job({ "git", "ls-files" }, make_entry),
|
finder = finders.new_oneshot_job(
|
||||||
|
{ "git", "ls-files", "-o", "--exclude-standard", "-c" },
|
||||||
|
make_entry.gen_from_file(opts)
|
||||||
|
),
|
||||||
previewer = previewers.cat,
|
previewer = previewers.cat,
|
||||||
sorter = sorters.get_fuzzy_file(),
|
sorter = sorters.get_fuzzy_file(),
|
||||||
}):find()
|
}):find()
|
||||||
end
|
end
|
||||||
|
|
||||||
builtin.live_grep = function(opts)
|
builtin.live_grep = function(opts)
|
||||||
local live_grepper = finders.new {
|
opts = opts or {}
|
||||||
fn_command = function(_, prompt)
|
|
||||||
-- TODO: Make it so that we can start searching on the first character.
|
local live_grepper = finders.new_job(function(prompt)
|
||||||
|
-- TODO: Probably could add some options for smart case and whatever else rg offers.
|
||||||
|
|
||||||
if not prompt or prompt == "" then
|
if not prompt or prompt == "" then
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
return {
|
return flatten { vimgrep_arguments, prompt }
|
||||||
command = 'rg',
|
end,
|
||||||
args = {"--vimgrep", prompt},
|
opts.entry_maker or make_entry.gen_from_vimgrep(opts),
|
||||||
}
|
opts.max_results
|
||||||
end
|
)
|
||||||
}
|
|
||||||
|
|
||||||
pickers.new(opts, {
|
pickers.new(opts, {
|
||||||
prompt = 'Live Grep',
|
prompt = 'Live Grep',
|
||||||
finder = live_grepper,
|
finder = live_grepper,
|
||||||
previewer = previewers.vimgrep,
|
previewer = previewers.vimgrep,
|
||||||
}):find()
|
}):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
|
|
||||||
-- old_files[f] = true
|
|
||||||
-- end
|
|
||||||
|
|
||||||
-- local oldfiles_sorter = sorters.new {
|
|
||||||
-- scoring_function = function(prompt, entry)
|
|
||||||
-- local line = entry.value
|
|
||||||
|
|
||||||
-- if not line then
|
|
||||||
-- return
|
|
||||||
-- end
|
|
||||||
|
|
||||||
-- local _, finish = string.find(line, ":")
|
|
||||||
-- local filename = string.sub(line, 1, finish - 1)
|
|
||||||
-- local expanded_fname = vim.fn.fnamemodify(filename, ':p')
|
|
||||||
-- if old_files[expanded_fname] then
|
|
||||||
-- print("Found oldfiles: ", entry.value)
|
|
||||||
-- return 0
|
|
||||||
-- else
|
|
||||||
-- return 1
|
|
||||||
-- end
|
|
||||||
-- end
|
|
||||||
-- }
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- TODO: document_symbol
|
-- TODO: document_symbol
|
||||||
-- TODO: workspace_symbol
|
-- TODO: workspace_symbol
|
||||||
|
|
||||||
builtin.lsp_references = function(opts)
|
builtin.lsp_references = function(opts)
|
||||||
|
opts = opts or {}
|
||||||
|
opts.shorten_path = utils.get_default(opts.shorten_path, true)
|
||||||
|
|
||||||
local params = vim.lsp.util.make_position_params()
|
local params = vim.lsp.util.make_position_params()
|
||||||
params.context = { includeDeclaration = true }
|
params.context = { includeDeclaration = true }
|
||||||
|
|
||||||
@@ -108,15 +83,74 @@ builtin.lsp_references = function(opts)
|
|||||||
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 = utils.quickfix_items_to_entries(locations)
|
if vim.tbl_isempty(locations) then
|
||||||
|
|
||||||
if vim.tbl_isempty(results) then
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local reference_picker = pickers.new(opts, {
|
pickers.new(opts, {
|
||||||
prompt = 'LSP References',
|
prompt = 'LSP References',
|
||||||
finder = finders.new_table(results),
|
finder = finders.new_table {
|
||||||
|
results = locations,
|
||||||
|
entry_maker = make_entry.gen_from_quickfix(opts),
|
||||||
|
},
|
||||||
|
previewer = previewers.qflist,
|
||||||
|
sorter = sorters.get_norcalli_sorter(),
|
||||||
|
}):find()
|
||||||
|
end
|
||||||
|
|
||||||
|
builtin.lsp_document_symbols = function(opts)
|
||||||
|
local params = vim.lsp.util.make_position_params()
|
||||||
|
local results_lsp = vim.lsp.buf_request_sync(0, "textDocument/documentSymbol", params)
|
||||||
|
|
||||||
|
if not results_lsp or vim.tbl_isempty(results_lsp) then
|
||||||
|
print("No results from textDocument/documentSymbol")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local locations = {}
|
||||||
|
for _, server_results in pairs(results_lsp) do
|
||||||
|
vim.list_extend(locations, vim.lsp.util.symbols_to_items(server_results.result, 0) or {})
|
||||||
|
end
|
||||||
|
|
||||||
|
if vim.tbl_isempty(locations) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
pickers.new(opts, {
|
||||||
|
prompt = 'LSP Document Symbols',
|
||||||
|
finder = finders.new_table {
|
||||||
|
results = locations,
|
||||||
|
entry_maker = make_entry.gen_from_quickfix(opts)
|
||||||
|
},
|
||||||
|
previewer = previewers.vim_buffer,
|
||||||
|
sorter = sorters.get_norcalli_sorter(),
|
||||||
|
}):find()
|
||||||
|
end
|
||||||
|
|
||||||
|
builtin.lsp_workspace_symbols = function(opts)
|
||||||
|
local params = {query = opts.query or ''}
|
||||||
|
local results_lsp = vim.lsp.buf_request_sync(0, "workspace/symbol", params, 1000)
|
||||||
|
|
||||||
|
if not results_lsp or vim.tbl_isempty(results_lsp) then
|
||||||
|
print("No results from textDocument/documentSymbol")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local locations = {}
|
||||||
|
for _, server_results in pairs(results_lsp) do
|
||||||
|
vim.list_extend(locations, vim.lsp.util.symbols_to_items(server_results.result, 0) or {})
|
||||||
|
end
|
||||||
|
|
||||||
|
if vim.tbl_isempty(locations) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
pickers.new(opts, {
|
||||||
|
prompt = 'LSP Workspace Symbols',
|
||||||
|
finder = finders.new_table {
|
||||||
|
results = locations,
|
||||||
|
entry_maker = make_entry.gen_from_quickfix(opts)
|
||||||
|
},
|
||||||
previewer = previewers.qflist,
|
previewer = previewers.qflist,
|
||||||
sorter = sorters.get_norcalli_sorter(),
|
sorter = sorters.get_norcalli_sorter(),
|
||||||
}):find()
|
}):find()
|
||||||
@@ -124,15 +158,17 @@ end
|
|||||||
|
|
||||||
builtin.quickfix = function(opts)
|
builtin.quickfix = function(opts)
|
||||||
local locations = vim.fn.getqflist()
|
local locations = vim.fn.getqflist()
|
||||||
local results = utils.quickfix_items_to_entries(locations)
|
|
||||||
|
|
||||||
if vim.tbl_isempty(results) then
|
if vim.tbl_isempty(locations) then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
pickers.new(opts, {
|
pickers.new(opts, {
|
||||||
prompt = 'Quickfix',
|
prompt = 'Quickfix',
|
||||||
finder = finders.new_table(results),
|
finder = finders.new_table {
|
||||||
|
results = locations,
|
||||||
|
entry_maker = make_entry.gen_from_quickfix(opts),
|
||||||
|
},
|
||||||
previewer = previewers.qflist,
|
previewer = previewers.qflist,
|
||||||
sorter = sorters.get_norcalli_sorter(),
|
sorter = sorters.get_norcalli_sorter(),
|
||||||
}):find()
|
}):find()
|
||||||
@@ -146,15 +182,16 @@ builtin.loclist = function(opts)
|
|||||||
value.filename = filename
|
value.filename = filename
|
||||||
end
|
end
|
||||||
|
|
||||||
local results = utils.quickfix_items_to_entries(locations)
|
if vim.tbl_isempty(locations) then
|
||||||
|
|
||||||
if vim.tbl_isempty(results) then
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
pickers.new(opts, {
|
pickers.new(opts, {
|
||||||
prompt = 'Loclist',
|
prompt = 'Loclist',
|
||||||
finder = finders.new_table(results),
|
finder = finders.new_table {
|
||||||
|
results = locations,
|
||||||
|
entry_maker = make_entry.gen_from_quickfix(opts),
|
||||||
|
},
|
||||||
previewer = previewers.qflist,
|
previewer = previewers.qflist,
|
||||||
sorter = sorters.get_norcalli_sorter(),
|
sorter = sorters.get_norcalli_sorter(),
|
||||||
}):find()
|
}):find()
|
||||||
@@ -165,9 +202,12 @@ builtin.grep_string = function(opts)
|
|||||||
|
|
||||||
local search = opts.search or vim.fn.expand("<cword>")
|
local search = opts.search or vim.fn.expand("<cword>")
|
||||||
|
|
||||||
local file_picker = pickers.new(opts, {
|
pickers.new(opts, {
|
||||||
prompt = 'Find Word',
|
prompt = 'Find Word',
|
||||||
finder = finders.new_oneshot_job {'rg', '--vimgrep', search},
|
finder = finders.new_oneshot_job(
|
||||||
|
flatten { vimgrep_arguments, search},
|
||||||
|
make_entry.gen_from_vimgrep(opts)
|
||||||
|
),
|
||||||
previewer = previewers.vimgrep,
|
previewer = previewers.vimgrep,
|
||||||
sorter = sorters.get_norcalli_sorter(),
|
sorter = sorters.get_norcalli_sorter(),
|
||||||
}):find()
|
}):find()
|
||||||
@@ -218,27 +258,32 @@ end
|
|||||||
-- vim.fn.setreg("+", "nnoremap $TODO :lua require('telescope.builtin').<whatever>()<CR>")
|
-- vim.fn.setreg("+", "nnoremap $TODO :lua require('telescope.builtin').<whatever>()<CR>")
|
||||||
-- TODO: Can we just do the names instead?
|
-- TODO: Can we just do the names instead?
|
||||||
builtin.builtin = function(opts)
|
builtin.builtin = function(opts)
|
||||||
|
opts = opts or {}
|
||||||
|
opts.hide_filename = utils.get_default(opts.hide_filename, true)
|
||||||
|
opts.ignore_filename = utils.get_default(opts.ignore_filename, true)
|
||||||
|
|
||||||
local objs = {}
|
local objs = {}
|
||||||
|
|
||||||
for k, v in pairs(builtin) do
|
for k, v in pairs(builtin) do
|
||||||
local debug_info = debug.getinfo(v)
|
local debug_info = debug.getinfo(v)
|
||||||
|
|
||||||
table.insert(objs, {
|
table.insert(objs, {
|
||||||
vimgrep_str = k,
|
|
||||||
filename = string.sub(debug_info.source, 2),
|
filename = string.sub(debug_info.source, 2),
|
||||||
lnum = debug_info.linedefined,
|
lnum = debug_info.linedefined,
|
||||||
col = 0,
|
col = 0,
|
||||||
|
text = k,
|
||||||
|
|
||||||
start = debug_info.linedefined,
|
start = debug_info.linedefined,
|
||||||
finish = debug_info.lastlinedefined,
|
finish = debug_info.lastlinedefined,
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
local entries = utils.quickfix_items_to_entries(objs)
|
|
||||||
|
|
||||||
pickers.new(opts, {
|
pickers.new(opts, {
|
||||||
prompt = 'Telescope Builtin',
|
prompt = 'Telescope Builtin',
|
||||||
finder = finders.new_table(entries),
|
finder = finders.new_table {
|
||||||
|
results = objs,
|
||||||
|
entry_maker = make_entry.gen_from_quickfix(opts),
|
||||||
|
},
|
||||||
previewer = previewers.qflist,
|
previewer = previewers.qflist,
|
||||||
sorter = sorters.get_norcalli_sorter(),
|
sorter = sorters.get_norcalli_sorter(),
|
||||||
}):find()
|
}):find()
|
||||||
@@ -269,14 +314,10 @@ builtin.fd = function(opts)
|
|||||||
|
|
||||||
pickers.new(opts, {
|
pickers.new(opts, {
|
||||||
prompt = 'Find Files',
|
prompt = 'Find Files',
|
||||||
finder = finders.new {
|
finder = finders.new_oneshot_job(
|
||||||
fn_command = function()
|
{fd_string},
|
||||||
return {
|
make_entry.gen_from_file(opts)
|
||||||
command = fd_string,
|
),
|
||||||
cwd = cwd,
|
|
||||||
}
|
|
||||||
end,
|
|
||||||
},
|
|
||||||
previewer = previewers.cat,
|
previewer = previewers.cat,
|
||||||
sorter = sorters.get_fuzzy_file(),
|
sorter = sorters.get_fuzzy_file(),
|
||||||
}):find()
|
}):find()
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
local Entry = {}
|
|
||||||
Entry.__index = Entry
|
|
||||||
|
|
||||||
-- TODO: Can we / should we make it so that "display" and "ordinal" are just values, instead of functions.
|
|
||||||
-- It seems like that's what you'd want... No need to call the functions a million times.
|
|
||||||
|
|
||||||
-- Pass in a table, that contains some state
|
|
||||||
-- Table determines it's ordinal value
|
|
||||||
function Entry:new(line_or_obj)
|
|
||||||
if type(line_or_obj) == "string" then
|
|
||||||
return setmetatable({
|
|
||||||
valid = line_or_obj ~= "",
|
|
||||||
|
|
||||||
value = line_or_obj,
|
|
||||||
ordinal = line_or_obj,
|
|
||||||
display = line_or_obj,
|
|
||||||
}, self)
|
|
||||||
else
|
|
||||||
return line_or_obj
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function Entry:__tostring()
|
|
||||||
return "<" .. self.display .. ">"
|
|
||||||
end
|
|
||||||
|
|
||||||
return Entry
|
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
local Job = require('plenary.job')
|
local Job = require('plenary.job')
|
||||||
|
|
||||||
|
local make_entry = require('telescope.make_entry')
|
||||||
local log = require('telescope.log')
|
local log = require('telescope.log')
|
||||||
local utils = require('telescope.utils')
|
local utils = require('telescope.utils')
|
||||||
|
|
||||||
@@ -10,35 +11,43 @@ local finders = {}
|
|||||||
-- FunctionFinder(my_func)
|
-- FunctionFinder(my_func)
|
||||||
-- JobFinder(my_job_args)
|
-- JobFinder(my_job_args)
|
||||||
|
|
||||||
---@class Finder
|
local _callable_obj = function()
|
||||||
local Finder = {}
|
local obj = {}
|
||||||
|
|
||||||
Finder.__index = Finder
|
obj.__index = obj
|
||||||
Finder.__call = function(t, ... ) return t:_find(...) end
|
obj.__call = function(t, ...) return t:_find(...) end
|
||||||
|
|
||||||
|
return obj
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--[[ =============================================================
|
||||||
|
|
||||||
|
JobFinder
|
||||||
|
|
||||||
|
Uses an external Job to get results. Processes results as they arrive.
|
||||||
|
|
||||||
|
For more information about how Jobs are implemented, checkout 'plenary.job'
|
||||||
|
|
||||||
|
-- ============================================================= ]]
|
||||||
|
local JobFinder = _callable_obj()
|
||||||
|
|
||||||
--- Create a new finder command
|
--- Create a new finder command
|
||||||
---
|
---
|
||||||
---@param opts table Keys:
|
---@param opts table Keys:
|
||||||
-- fn_command function The function to call
|
-- fn_command function The function to call
|
||||||
function Finder:new(opts)
|
function JobFinder:new(opts)
|
||||||
opts = opts or {}
|
opts = opts or {}
|
||||||
|
|
||||||
-- TODO: Add config for:
|
assert(not opts.results, "`results` should be used with finder.new_table")
|
||||||
-- - cwd
|
|
||||||
|
|
||||||
-- TODO:
|
-- TODO:
|
||||||
-- - `types`
|
-- - `types`
|
||||||
-- job
|
-- job
|
||||||
-- pipe
|
-- pipe
|
||||||
-- vim.loop.new_pipe (stdin / stdout). stdout => filter pipe
|
-- vim.loop.new_pipe (stdin / stdout). stdout => filter pipe
|
||||||
-- rg huge_search | fzf --filter prompt_is > buffer. buffer could do stuff do w/ preview callback
|
-- rg huge_search | fzf --filter prompt_is > buffer. buffer could do stuff do w/ preview callback
|
||||||
-- string
|
|
||||||
-- list
|
|
||||||
-- ...
|
|
||||||
local obj = setmetatable({
|
local obj = setmetatable({
|
||||||
results = opts.results,
|
entry_maker = opts.entry_maker or make_entry.from_string,
|
||||||
|
|
||||||
entry_maker = opts.entry_maker,
|
|
||||||
fn_command = opts.fn_command,
|
fn_command = opts.fn_command,
|
||||||
static = opts.static,
|
static = opts.static,
|
||||||
state = {},
|
state = {},
|
||||||
@@ -51,26 +60,7 @@ function Finder:new(opts)
|
|||||||
return obj
|
return obj
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Probably should use the word apply here, since we're apply the callback passed to us by
|
function JobFinder:_find(prompt, process_result, process_complete)
|
||||||
-- the picker... But I'm not sure how we want to say that.
|
|
||||||
|
|
||||||
-- find_incremental
|
|
||||||
-- find_prompt
|
|
||||||
-- process_prompt
|
|
||||||
-- process_search
|
|
||||||
-- do_your_job
|
|
||||||
-- process_plz
|
|
||||||
function Finder:_find(prompt, process_result, process_complete)
|
|
||||||
if self.results then
|
|
||||||
assert(type(self.results) == 'table', "self.results must be a table")
|
|
||||||
for _, v in ipairs(self.results) do
|
|
||||||
process_result(v)
|
|
||||||
end
|
|
||||||
|
|
||||||
process_complete()
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if self.job and not self.job.is_shutdown then
|
if self.job and not self.job.is_shutdown then
|
||||||
self.job:shutdown()
|
self.job:shutdown()
|
||||||
end
|
end
|
||||||
@@ -140,22 +130,66 @@ function Finder:_find(prompt, process_result, process_complete)
|
|||||||
self.job:start()
|
self.job:start()
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Return a new Finder
|
--[[ =============================================================
|
||||||
--
|
Static Finders
|
||||||
--@return Finder
|
|
||||||
finders.new = function(opts)
|
A static finder has results that never change.
|
||||||
return Finder:new(opts)
|
They are passed in directly as a result.
|
||||||
|
-- ============================================================= ]]
|
||||||
|
local StaticFinder = _callable_obj()
|
||||||
|
|
||||||
|
function StaticFinder:new(opts)
|
||||||
|
assert(opts, "Options are required. See documentation for usage")
|
||||||
|
|
||||||
|
local input_results
|
||||||
|
if vim.tbl_islist(opts) then
|
||||||
|
input_results = opts
|
||||||
|
else
|
||||||
|
input_results = opts.results
|
||||||
|
end
|
||||||
|
|
||||||
|
local entry_maker = opts.entry_maker or make_entry.gen_from_string()
|
||||||
|
|
||||||
|
assert(input_results)
|
||||||
|
assert(input_results, "Results are required for static finder")
|
||||||
|
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))
|
||||||
|
end
|
||||||
|
|
||||||
|
return setmetatable({ results = results }, self)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- TODO: Is this worth making?
|
function StaticFinder:_find(_, process_result, process_complete)
|
||||||
-- finders.new_responsive_job = function(opts)
|
for _, v in ipairs(self.results) do
|
||||||
-- return finders.new {
|
process_result(v)
|
||||||
-- maximum_results = get_default(opts.maximum_results, 2000),
|
end
|
||||||
-- }
|
|
||||||
-- end
|
|
||||||
|
|
||||||
finders.new_job = function(command_generator)
|
process_complete()
|
||||||
return finders.new {
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- local
|
||||||
|
|
||||||
|
|
||||||
|
--- Return a new Finder
|
||||||
|
--
|
||||||
|
-- Use at your own risk.
|
||||||
|
-- This opts dictionary is likely to change, but you are welcome to use it right now.
|
||||||
|
-- I will try not to change it needlessly, but I will change it sometimes and I won't feel bad.
|
||||||
|
finders._new = function(opts)
|
||||||
|
if opts.results then
|
||||||
|
print("finder.new is deprecated with `results`. You should use `finder.new_table`")
|
||||||
|
return StaticFinder:new(opts)
|
||||||
|
end
|
||||||
|
|
||||||
|
return JobFinder:new(opts)
|
||||||
|
end
|
||||||
|
|
||||||
|
finders.new_job = function(command_generator, entry_maker, maximum_results)
|
||||||
|
return JobFinder:new {
|
||||||
fn_command = function(_, prompt)
|
fn_command = function(_, prompt)
|
||||||
local command_list = command_generator(prompt)
|
local command_list = command_generator(prompt)
|
||||||
if command_list == nil then
|
if command_list == nil then
|
||||||
@@ -168,19 +202,24 @@ finders.new_job = function(command_generator)
|
|||||||
command = command,
|
command = command,
|
||||||
args = command_list,
|
args = command_list,
|
||||||
}
|
}
|
||||||
end
|
end,
|
||||||
|
|
||||||
|
entry_maker = entry_maker,
|
||||||
|
maximum_results = maximum_results,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@param command_list string[] Command list to execute.
|
||||||
|
---@param entry_maker function Optional: function(line: string) => table
|
||||||
finders.new_oneshot_job = function(command_list, entry_maker)
|
finders.new_oneshot_job = function(command_list, entry_maker)
|
||||||
command_list = vim.deepcopy(command_list)
|
command_list = vim.deepcopy(command_list)
|
||||||
|
|
||||||
local command = table.remove(command_list, 1)
|
local command = table.remove(command_list, 1)
|
||||||
|
|
||||||
return finders.new {
|
return JobFinder:new {
|
||||||
static = true,
|
static = true,
|
||||||
|
|
||||||
entry_maker = entry_maker,
|
entry_maker = entry_maker or make_entry.from_string,
|
||||||
|
|
||||||
fn_command = function()
|
fn_command = function()
|
||||||
return {
|
return {
|
||||||
@@ -191,18 +230,14 @@ finders.new_oneshot_job = function(command_list, entry_maker)
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Used to create a finder for a Lua table.
|
||||||
|
-- If you only pass a table of results, then it will use that as the entries.
|
||||||
|
--
|
||||||
|
-- If you pass a table, and then a function, it's used as:
|
||||||
|
-- results table, the results to run on
|
||||||
|
-- entry_maker function, the function to convert results to entries.
|
||||||
finders.new_table = function(t)
|
finders.new_table = function(t)
|
||||||
return finders.new {
|
return StaticFinder:new(t)
|
||||||
results = t
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- We should add a few utility functions here...
|
|
||||||
--
|
|
||||||
-- finders.new_job
|
|
||||||
-- finders.new_one_shot_job
|
|
||||||
-- finders.new_table
|
|
||||||
|
|
||||||
-- finders.Finder = Finder
|
|
||||||
|
|
||||||
return finders
|
return finders
|
||||||
|
|||||||
162
lua/telescope/make_entry.lua
Normal file
162
lua/telescope/make_entry.lua
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
local has_devicons, devicons = pcall(require, 'nvim-web-devicons')
|
||||||
|
|
||||||
|
local utils = require('telescope.utils')
|
||||||
|
|
||||||
|
local make_entry = {}
|
||||||
|
|
||||||
|
make_entry.types = {
|
||||||
|
GENERIC = 0,
|
||||||
|
FILE = 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
local transform_devicons
|
||||||
|
if has_devicons then
|
||||||
|
transform_devicons = function(filename, display, opts)
|
||||||
|
if opts.disable_devicons then
|
||||||
|
return display
|
||||||
|
end
|
||||||
|
|
||||||
|
return (devicons.get_icon(filename, string.match(filename, '%a+$')) or ' ') .. ' ' .. display
|
||||||
|
end
|
||||||
|
else
|
||||||
|
transform_devicons = function(_, display, _)
|
||||||
|
return display
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function make_entry.gen_from_string()
|
||||||
|
return function(line)
|
||||||
|
return {
|
||||||
|
valid = line ~= "",
|
||||||
|
entry_type = make_entry.types.SIMPLE,
|
||||||
|
|
||||||
|
value = line,
|
||||||
|
ordinal = line,
|
||||||
|
display = line,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function make_entry.gen_from_file(opts)
|
||||||
|
opts = opts or {}
|
||||||
|
|
||||||
|
local make_display = function(line)
|
||||||
|
local display = line
|
||||||
|
if opts.shorten_path then
|
||||||
|
display = utils.path_shorten(line)
|
||||||
|
end
|
||||||
|
|
||||||
|
display = transform_devicons(line, display, opts)
|
||||||
|
|
||||||
|
return display
|
||||||
|
end
|
||||||
|
|
||||||
|
return function(line)
|
||||||
|
local entry = {
|
||||||
|
ordinal = line,
|
||||||
|
value = line,
|
||||||
|
|
||||||
|
entry_type = make_entry.types.FILE,
|
||||||
|
filename = line,
|
||||||
|
}
|
||||||
|
|
||||||
|
entry.display = make_display(line)
|
||||||
|
|
||||||
|
return entry
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function make_entry.gen_from_vimgrep(opts)
|
||||||
|
opts = opts or {}
|
||||||
|
|
||||||
|
local display_string = "%s:%s%s"
|
||||||
|
|
||||||
|
local make_display = function(entry)
|
||||||
|
local display = entry.value
|
||||||
|
|
||||||
|
local display_filename
|
||||||
|
if opts.shorten_path then
|
||||||
|
display_filename = utils.path_shorten(entry.filename)
|
||||||
|
else
|
||||||
|
display_filename = entry.filename
|
||||||
|
end
|
||||||
|
|
||||||
|
local coordinates = ""
|
||||||
|
if not opts.disable_coordinates then
|
||||||
|
coordinates = string.format("%s:%s:", entry.lnum, entry.col)
|
||||||
|
end
|
||||||
|
|
||||||
|
display = transform_devicons(
|
||||||
|
entry.filename,
|
||||||
|
string.format(display_string, display_filename, coordinates, entry.text),
|
||||||
|
opts
|
||||||
|
)
|
||||||
|
|
||||||
|
return display
|
||||||
|
end
|
||||||
|
|
||||||
|
return function(line)
|
||||||
|
-- TODO: Consider waiting to do this string.find
|
||||||
|
-- TODO: Is this the fastest way to get each of these?
|
||||||
|
-- Or could we just walk the text and check for colons faster?
|
||||||
|
local _, _, filename, lnum, col, text = string.find(line, [[([^:]+):(%d+):(%d+):(.*)]])
|
||||||
|
|
||||||
|
return {
|
||||||
|
valid = line ~= "",
|
||||||
|
|
||||||
|
value = line,
|
||||||
|
ordinal = line,
|
||||||
|
display = make_display,
|
||||||
|
|
||||||
|
entry_type = make_entry.types.FILE,
|
||||||
|
filename = filename,
|
||||||
|
lnum = lnum,
|
||||||
|
col = col,
|
||||||
|
text = text,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function make_entry.gen_from_quickfix(opts)
|
||||||
|
opts = opts or {}
|
||||||
|
|
||||||
|
local make_display = function(entry)
|
||||||
|
local to_concat = {}
|
||||||
|
|
||||||
|
if not opts.hide_filename then
|
||||||
|
local filename = entry.filename
|
||||||
|
if opts.shorten_path then
|
||||||
|
filename = utils.path_shorten(filename)
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(to_concat, filename)
|
||||||
|
table.insert(to_concat, ":")
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(to_concat, entry.text)
|
||||||
|
|
||||||
|
return table.concat(to_concat, "")
|
||||||
|
end
|
||||||
|
|
||||||
|
return function(entry)
|
||||||
|
return {
|
||||||
|
valid = true,
|
||||||
|
|
||||||
|
value = entry,
|
||||||
|
ordinal = (
|
||||||
|
not opts.ignore_filename and entry.filename
|
||||||
|
or ''
|
||||||
|
) .. ' ' .. entry.text,
|
||||||
|
display = make_display,
|
||||||
|
|
||||||
|
filename = entry.filename,
|
||||||
|
lnum = entry.lnum,
|
||||||
|
col = entry.col,
|
||||||
|
text = entry.text,
|
||||||
|
start = entry.start,
|
||||||
|
finish = entry.finish,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return make_entry
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
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,8 +7,6 @@ local mappings = require('telescope.mappings')
|
|||||||
local state = require('telescope.state')
|
local state = require('telescope.state')
|
||||||
local utils = require('telescope.utils')
|
local utils = require('telescope.utils')
|
||||||
|
|
||||||
local Entry = require('telescope.entry')
|
|
||||||
|
|
||||||
local get_default = utils.get_default
|
local get_default = utils.get_default
|
||||||
|
|
||||||
-- TODO: Make this work with deep extend I think.
|
-- TODO: Make this work with deep extend I think.
|
||||||
@@ -255,14 +252,19 @@ function Picker:find()
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- TODO: This really isn't the place to do this.
|
local display
|
||||||
local display = entry.display
|
if type(entry.display) == 'function' then
|
||||||
|
display = entry:display()
|
||||||
if has_devicons then
|
elseif type(entry.display) == 'string' then
|
||||||
local icon = devicons.get_icon(display, vim.fn.fnamemodify(display, ":e"))
|
display = entry.display
|
||||||
display = (icon or ' ') .. ' ' .. display
|
else
|
||||||
|
log.info("Weird entry", entry)
|
||||||
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- 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
|
||||||
display = ' ' .. display
|
display = ' ' .. display
|
||||||
|
|
||||||
-- log.info("Setting row", row, "with value", entry)
|
-- log.info("Setting row", row, "with value", entry)
|
||||||
@@ -277,10 +279,9 @@ function Picker:find()
|
|||||||
end
|
end
|
||||||
))
|
))
|
||||||
|
|
||||||
local process_result = function(line)
|
local process_result = function(entry)
|
||||||
local entry = Entry:new(line)
|
-- TODO: Should we even have valid?
|
||||||
|
if entry.valid == false then
|
||||||
if not entry.valid then
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -559,10 +560,7 @@ pickers.entry_manager = function(max_results, set_entry)
|
|||||||
|
|
||||||
return setmetatable({
|
return setmetatable({
|
||||||
add_entry = function(self, score, entry)
|
add_entry = function(self, score, entry)
|
||||||
-- TODO: Consider forcing people to make these entries before we add them.
|
assert(type(entry) == "table", "entry must be a table by the time it reaches here")
|
||||||
if type(entry) == "string" then
|
|
||||||
entry = Entry:new(entry)
|
|
||||||
end
|
|
||||||
|
|
||||||
score = score or 0
|
score = score or 0
|
||||||
|
|
||||||
@@ -647,6 +645,10 @@ function pickers.on_close_prompt(prompt_bufnr)
|
|||||||
local picker = status.picker
|
local picker = status.picker
|
||||||
|
|
||||||
picker:close_windows(status)
|
picker:close_windows(status)
|
||||||
|
|
||||||
|
if picker.previewer then
|
||||||
|
picker.previewer:teardown()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ local Previewer = {}
|
|||||||
Previewer.__index = Previewer
|
Previewer.__index = Previewer
|
||||||
|
|
||||||
local bat_options = " --style=grid --paging=always "
|
local bat_options = " --style=grid --paging=always "
|
||||||
|
local previewer_ns = vim.api.nvim_create_namespace('telescope.previewers')
|
||||||
-- --terminal-width=%s
|
-- --terminal-width=%s
|
||||||
|
|
||||||
-- TODO: We shoudl make sure that all our terminals close all the way.
|
-- TODO: We shoudl make sure that all our terminals close all the way.
|
||||||
@@ -20,6 +21,7 @@ function Previewer:new(opts)
|
|||||||
return setmetatable({
|
return setmetatable({
|
||||||
state = nil,
|
state = nil,
|
||||||
_setup_func = opts.setup,
|
_setup_func = opts.setup,
|
||||||
|
_teardown_func = opts.teardown,
|
||||||
preview_fn = opts.preview_fn,
|
preview_fn = opts.preview_fn,
|
||||||
}, Previewer)
|
}, Previewer)
|
||||||
end
|
end
|
||||||
@@ -29,13 +31,22 @@ function Previewer:preview(entry, status)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if not self.state and self._setup_func then
|
if not self.state then
|
||||||
|
if self._setup_func then
|
||||||
self.state = self._setup_func()
|
self.state = self._setup_func()
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
self:teardown()
|
||||||
return self:preview_fn(entry, status)
|
return self:preview_fn(entry, status)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Previewer:teardown()
|
||||||
|
if self._teardown_func then
|
||||||
|
self:_teardown_func()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
previewers.new = function(...)
|
previewers.new = function(...)
|
||||||
return Previewer:new(...)
|
return Previewer:new(...)
|
||||||
end
|
end
|
||||||
@@ -69,20 +80,36 @@ previewers.new_termopen = function(opts)
|
|||||||
end
|
end
|
||||||
|
|
||||||
previewers.vim_buffer = previewers.new {
|
previewers.vim_buffer = previewers.new {
|
||||||
preview_fn = function(_, entry, status)
|
setup = function() return { last_set_bufnr = nil } end,
|
||||||
|
|
||||||
|
teardown = function(self)
|
||||||
|
if self.state.last_set_bufnr then
|
||||||
|
vim.api.nvim_buf_clear_namespace(self.state.last_set_bufnr, previewer_ns, 0, -1)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
|
preview_fn = function(self, entry, status)
|
||||||
|
local filename = entry.filename
|
||||||
|
|
||||||
|
if filename == nil then
|
||||||
local value = entry.value
|
local value = entry.value
|
||||||
if value == nil then
|
filename = vim.split(value, ":")[1]
|
||||||
|
end
|
||||||
|
|
||||||
|
if filename == nil then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local file_name = vim.split(value, ":")[1]
|
|
||||||
|
|
||||||
log.trace("Previewing File: %s", file_name)
|
log.trace("Previewing File: %s", filename)
|
||||||
|
|
||||||
-- vim.fn.termopen(
|
local bufnr = vim.fn.bufnr(filename)
|
||||||
-- string.format("bat --color=always --style=grid %s"),
|
if bufnr == -1 then
|
||||||
-- vim.fn.fnamemodify(file_name, ":p")
|
-- TODO: Is this the best way to load the buffer?... I'm not sure tbh
|
||||||
local bufnr = vim.fn.bufadd(file_name)
|
bufnr = vim.fn.bufadd(bufnr)
|
||||||
vim.fn.bufload(bufnr)
|
vim.fn.bufload(bufnr)
|
||||||
|
end
|
||||||
|
|
||||||
|
self.state.last_set_bufnr = bufnr
|
||||||
|
|
||||||
-- TODO: We should probably call something like this because we're not always getting highlight and all that stuff.
|
-- TODO: We should probably call something like this because we're not always getting highlight and all that stuff.
|
||||||
-- api.nvim_command('doautocmd filetypedetect BufRead ' .. vim.fn.fnameescape(filename))
|
-- api.nvim_command('doautocmd filetypedetect BufRead ' .. vim.fn.fnameescape(filename))
|
||||||
@@ -92,6 +119,11 @@ previewers.vim_buffer = previewers.new {
|
|||||||
-- vim.api.nvim_win_set_option(preview_win, 'winblend', 20)
|
-- vim.api.nvim_win_set_option(preview_win, 'winblend', 20)
|
||||||
vim.api.nvim_win_set_option(status.preview_win, 'signcolumn', 'no')
|
vim.api.nvim_win_set_option(status.preview_win, 'signcolumn', 'no')
|
||||||
vim.api.nvim_win_set_option(status.preview_win, 'foldlevel', 100)
|
vim.api.nvim_win_set_option(status.preview_win, 'foldlevel', 100)
|
||||||
|
|
||||||
|
if entry.lnum then
|
||||||
|
vim.api.nvim_buf_add_highlight(bufnr, previewer_ns, "Visual", entry.lnum - 1, 0, -1)
|
||||||
|
-- print("LNUM:", entry.lnum)
|
||||||
|
end
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -99,6 +99,10 @@ utils.path_shorten = (function()
|
|||||||
]]
|
]]
|
||||||
|
|
||||||
return function(path)
|
return function(path)
|
||||||
|
if not path then
|
||||||
|
return path
|
||||||
|
end
|
||||||
|
|
||||||
local c_str = ffi.new("char[?]", #path + 1)
|
local c_str = ffi.new("char[?]", #path + 1)
|
||||||
ffi.copy(c_str, path)
|
ffi.copy(c_str, path)
|
||||||
return ffi.string(ffi.C.shorten_dir(c_str))
|
return ffi.string(ffi.C.shorten_dir(c_str))
|
||||||
|
|||||||
@@ -1,15 +1,21 @@
|
|||||||
RELOAD('telescope')
|
require('plenary.reload').reload_module('telescope')
|
||||||
|
|
||||||
local actions = require('telescope.actions')
|
|
||||||
local finders = require('telescope.finders')
|
local finders = require('telescope.finders')
|
||||||
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')
|
|
||||||
|
|
||||||
|
|
||||||
pickers.new({
|
pickers.new({
|
||||||
prompt = 'Telescope Builtin',
|
prompt = 'Telescope Builtin',
|
||||||
finder = finders.new_table({"hello\nworld", "other", "item"}),
|
finder = finders.new_table {
|
||||||
|
results = {"hello\nworld", "other", "item"},
|
||||||
|
entry_maker = false and function(line)
|
||||||
|
return {
|
||||||
|
value = line,
|
||||||
|
ordinal = line,
|
||||||
|
display = "wow: // " .. line,
|
||||||
|
}
|
||||||
|
end,
|
||||||
|
},
|
||||||
sorter = sorters.get_norcalli_sorter(),
|
sorter = sorters.get_norcalli_sorter(),
|
||||||
}):find()
|
}):find()
|
||||||
|
|||||||
26
media/worflow.txt
Normal file
26
media/worflow.txt
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
+-------------------------------------------------------------------+
|
||||||
|
| Picker:find()--------------------+ +------>Picker |
|
||||||
|
| | ^ | | |
|
||||||
|
| | | v | |
|
||||||
|
| | +----------------+ +----------------+ |
|
||||||
|
| +->| Finder + | Sorter | |
|
||||||
|
| +----------------+ +----------------+ |
|
||||||
|
| [1] |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
+-------------------------------------------------------------------+
|
||||||
|
|
||||||
|
Picker starts a `finder`.
|
||||||
|
Finder returns a list of `entries` to Picker.
|
||||||
|
Picker can optionally sort w/ `Sorter`.
|
||||||
|
Picker can optionally preview selected with `Previewer`
|
||||||
|
|
||||||
|
Then you can map stuff in the picker to decide what to do next.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
55
scratch/batched_finder_and_sorter.lua
Normal file
55
scratch/batched_finder_and_sorter.lua
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
local actions = require('telescope.actions')
|
||||||
|
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 Job = require('plenary.job')
|
||||||
|
|
||||||
|
-- local live_grepper = finders.new {
|
||||||
|
-- fn_command = function(_, prompt)
|
||||||
|
-- -- TODO: Make it so that we can start searching on the first character.
|
||||||
|
-- if not prompt or prompt == "" then
|
||||||
|
-- return nil
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- return {
|
||||||
|
-- command = 'rg',
|
||||||
|
-- args = {"--vimgrep", prompt},
|
||||||
|
-- }
|
||||||
|
-- end
|
||||||
|
-- }
|
||||||
|
|
||||||
|
local f = function(prompt, process_result, process_complete)
|
||||||
|
local fzf = Job:new {
|
||||||
|
command = 'fzf';
|
||||||
|
|
||||||
|
writer = Job:new {
|
||||||
|
command = "fdfind",
|
||||||
|
args = nil,
|
||||||
|
cwd = "/home/tj/build/neovim",
|
||||||
|
|
||||||
|
enable_handlers = false,
|
||||||
|
},
|
||||||
|
|
||||||
|
-- Still doesn't work if you don't pass these args and just run `fzf`
|
||||||
|
args = {'--no-sort', '--filter', prompt};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
local start = vim.fn.reltime()
|
||||||
|
print(vim.inspect(fzf:sync()), vim.fn.reltimestr(vim.fn.reltime(start)))
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Process all the files
|
||||||
|
-- f("", nil, nil)
|
||||||
|
-- Filter on nvimexec
|
||||||
|
f("nvim/executor", nil, nil)
|
||||||
|
|
||||||
|
-- pickers.new({}, {
|
||||||
|
-- prompt = 'Live Grep',
|
||||||
|
-- finder = f,
|
||||||
|
-- previewer = previewers.vimgrep,
|
||||||
|
-- }):find()
|
||||||
130
scratch/clason_finders.lua
Normal file
130
scratch/clason_finders.lua
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
vim.cmd [[packadd! plenary.nvim]]
|
||||||
|
vim.cmd [[packadd! popup.nvim]]
|
||||||
|
vim.cmd [[packadd! telescope.nvim]]
|
||||||
|
|
||||||
|
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 rgargs = {'--color=never', '--no-heading', '--with-filename', '--line-number', '--column', '--smart-case'}
|
||||||
|
-- grep typed string in current directory (live, not fuzzy!)
|
||||||
|
finders.rg_live = function(opts)
|
||||||
|
local live_grepper = finders.new {
|
||||||
|
fn_command = function(_, prompt)
|
||||||
|
if not prompt or prompt == "" then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
return {
|
||||||
|
command = 'rg',
|
||||||
|
args = vim.tbl_flatten{rgargs, prompt},
|
||||||
|
}
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
pickers.new(opts, {
|
||||||
|
prompt = 'Live Grep',
|
||||||
|
finder = live_grepper,
|
||||||
|
previewer = previewers.vimgrep,
|
||||||
|
}):find()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- fuzzy grep string in current directory (slow!)
|
||||||
|
finders.rg = function(opts)
|
||||||
|
opts = opts or {}
|
||||||
|
|
||||||
|
local search = opts.search or ''
|
||||||
|
|
||||||
|
pickers.new(opts, {
|
||||||
|
prompt = 'Find Word',
|
||||||
|
finder = finders.new_oneshot_job(vim.tbl_flatten{'rg', rgargs, search}),
|
||||||
|
previewer = previewers.vimgrep,
|
||||||
|
sorter = sorters.get_norcalli_sorter(),
|
||||||
|
}):find()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- fuzzy find files in current directory (may be slow in root dir)
|
||||||
|
finders.fd = function(opts)
|
||||||
|
pickers.new(opts, {
|
||||||
|
prompt = 'Find Files',
|
||||||
|
finder = finders.new_oneshot_job {"fd"},
|
||||||
|
previewer = previewers.bat,
|
||||||
|
sorter = sorters.get_fuzzy_file(),
|
||||||
|
}):find()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- fuzzy find in references to symbol under cursor
|
||||||
|
finders.lsp_references = function(opts)
|
||||||
|
local params = vim.lsp.util.make_position_params()
|
||||||
|
params.context = { includeDeclaration = false }
|
||||||
|
|
||||||
|
local results_lsp = vim.lsp.buf_request_sync(0, "textDocument/references", params)
|
||||||
|
local locations = {}
|
||||||
|
for _, server_results in pairs(results_lsp) do
|
||||||
|
vim.list_extend(locations, vim.lsp.util.locations_to_items(server_results.result) or {})
|
||||||
|
end
|
||||||
|
|
||||||
|
local results = utils.quickfix_items_to_entries(locations)
|
||||||
|
|
||||||
|
if vim.tbl_isempty(results) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
pickers.new(opts, {
|
||||||
|
prompt = 'LSP References',
|
||||||
|
finder = finders.new_table(results),
|
||||||
|
previewer = previewers.qflist,
|
||||||
|
sorter = sorters.get_norcalli_sorter(),
|
||||||
|
}):find()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- fuzzy find in document symbols
|
||||||
|
finders.lsp_document_symbols = function(opts)
|
||||||
|
local params = vim.lsp.util.make_position_params()
|
||||||
|
local results_lsp = vim.lsp.buf_request_sync(0, "textDocument/documentSymbol", params)
|
||||||
|
local locations = {}
|
||||||
|
for _, server_results in pairs(results_lsp) do
|
||||||
|
vim.list_extend(locations, vim.lsp.util.symbols_to_items(server_results.result, 0) or {})
|
||||||
|
end
|
||||||
|
|
||||||
|
local results = utils.quickfix_items_to_entries(locations)
|
||||||
|
|
||||||
|
if vim.tbl_isempty(results) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
pickers.new(opts, {
|
||||||
|
prompt = 'LSP Document Symbols',
|
||||||
|
finder = finders.new_table(results),
|
||||||
|
previewer = previewers.qflist,
|
||||||
|
sorter = sorters.get_norcalli_sorter(),
|
||||||
|
}):find()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- fuzzy find in all workspace symbols (may need longer timeout!)
|
||||||
|
finders.lsp_workspace_symbols = function(opts)
|
||||||
|
local params = {query = ''}
|
||||||
|
local results_lsp = vim.lsp.buf_request_sync(0, "workspace/symbol", params, 1000)
|
||||||
|
local locations = {}
|
||||||
|
for _, server_results in pairs(results_lsp) do
|
||||||
|
vim.list_extend(locations, vim.lsp.util.symbols_to_items(server_results.result, 0) or {})
|
||||||
|
end
|
||||||
|
|
||||||
|
local results = utils.quickfix_items_to_entries(locations)
|
||||||
|
|
||||||
|
if vim.tbl_isempty(results) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
pickers.new(opts, {
|
||||||
|
prompt = 'LSP Workspace Symbols',
|
||||||
|
finder = finders.new_table(results),
|
||||||
|
previewer = previewers.qflist,
|
||||||
|
sorter = sorters.get_norcalli_sorter(),
|
||||||
|
}):find()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
return finders
|
||||||
Reference in New Issue
Block a user