summaryrefslogtreecommitdiff
path: root/lua
diff options
context:
space:
mode:
authorSimon Hauser <Simon-Hauser@outlook.de>2020-11-26 08:16:58 +0100
committerGitHub <noreply@github.com>2020-11-26 08:16:58 +0100
commit4a8ea7763ec3c1c0672398418da682c1e0d4017d (patch)
tree916242a10f9b2c67e6f8e8b3a2604df073a19871 /lua
parent0f9fd84a9742e22294cfaf46f32bad9b29de0b31 (diff)
Refactor builtin (#287)
Diffstat (limited to 'lua')
-rw-r--r--lua/telescope/builtin/files.lua248
-rw-r--r--lua/telescope/builtin/init.lua1037
-rw-r--r--lua/telescope/builtin/internal.lua595
-rw-r--r--lua/telescope/builtin/lsp.lua182
-rw-r--r--lua/telescope/make_entry.lua2
-rw-r--r--lua/telescope/previewers.lua40
6 files changed, 1098 insertions, 1006 deletions
diff --git a/lua/telescope/builtin/files.lua b/lua/telescope/builtin/files.lua
new file mode 100644
index 0000000..d1484ed
--- /dev/null
+++ b/lua/telescope/builtin/files.lua
@@ -0,0 +1,248 @@
+local actions = require('telescope.actions')
+local finders = require('telescope.finders')
+local make_entry = require('telescope.make_entry')
+local pickers = require('telescope.pickers')
+local previewers = require('telescope.previewers')
+local utils = require('telescope.utils')
+
+local conf = require('telescope.config').values
+
+local flatten = vim.tbl_flatten
+
+local files = {}
+
+files.live_grep = function(opts)
+ 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
+ return nil
+ end
+
+ return flatten { conf.vimgrep_arguments, prompt }
+ end,
+ opts.entry_maker or make_entry.gen_from_vimgrep(opts),
+ opts.max_results
+ )
+
+ pickers.new(opts, {
+ prompt_title = 'Live Grep',
+ finder = live_grepper,
+ previewer = previewers.vimgrep.new(opts),
+ sorter = conf.generic_sorter(opts),
+ }):find()
+end
+
+-- Special keys:
+-- opts.search -- the string to search.
+files.grep_string = function(opts)
+ -- TODO: This should probably check your visual selection as well, if you've got one
+ local search = opts.search or vim.fn.expand("<cword>")
+
+ opts.entry_maker = opts.entry_maker or make_entry.gen_from_vimgrep(opts)
+ opts.word_match = opts.word_match or nil
+
+ pickers.new(opts, {
+ prompt_title = 'Find Word',
+ finder = finders.new_oneshot_job(
+ flatten { conf.vimgrep_arguments, opts.word_match, search},
+ opts
+ ),
+ previewer = previewers.vimgrep.new(opts),
+ sorter = conf.generic_sorter(opts),
+ }):find()
+end
+
+-- TODO: Maybe just change this to `find`.
+-- Support `find` and maybe let people do other stuff with it as well.
+files.find_files = function(opts)
+ local find_command = opts.find_command
+
+ if not find_command then
+ if 1 == vim.fn.executable("fd") then
+ find_command = { 'fd', '--type', 'f' }
+ elseif 1 == vim.fn.executable("fdfind") then
+ find_command = { 'fdfind', '--type', 'f' }
+ elseif 1 == vim.fn.executable("rg") then
+ find_command = { 'rg', '--files' }
+ elseif 1 == vim.fn.executable("find") then
+ find_command = { 'find', '.', '-type', 'f' }
+ end
+ end
+
+ if not find_command then
+ print("You need to install either find, fd, or rg. You can also submit a PR to add support for another file finder :)")
+ return
+ end
+
+ if opts.cwd then
+ opts.cwd = vim.fn.expand(opts.cwd)
+ end
+
+ opts.entry_maker = opts.entry_maker or make_entry.gen_from_file(opts)
+
+ pickers.new(opts, {
+ prompt_title = 'Find Files',
+ finder = finders.new_oneshot_job(
+ find_command,
+ opts
+ ),
+ previewer = previewers.cat.new(opts),
+ sorter = conf.file_sorter(opts),
+ }):find()
+end
+
+local function prepare_match(entry, kind)
+ local entries = {}
+
+ if entry.node then
+ entry["kind"] = kind
+ table.insert(entries, entry)
+ else
+ for name, item in pairs(entry) do
+ vim.list_extend(entries, prepare_match(item, name))
+ end
+ end
+
+ return entries
+end
+
+files.treesitter = function(opts)
+ opts.show_line = utils.get_default(opts.show_line, true)
+
+ local has_nvim_treesitter, _ = pcall(require, 'nvim-treesitter')
+ if not has_nvim_treesitter then
+ print('You need to install nvim-treesitter')
+ return
+ end
+
+ local parsers = require('nvim-treesitter.parsers')
+ if not parsers.has_parser() then
+ print('No parser for the current buffer')
+ return
+ end
+
+ local ts_locals = require('nvim-treesitter.locals')
+ local bufnr = opts.bufnr or vim.api.nvim_get_current_buf()
+
+ local results = {}
+ for _, definitions in ipairs(ts_locals.get_definitions(bufnr)) do
+ local entries = prepare_match(definitions)
+ for _, entry in ipairs(entries) do
+ table.insert(results, entry)
+ end
+ end
+
+ if vim.tbl_isempty(results) then
+ return
+ end
+
+ pickers.new(opts, {
+ prompt_title = 'Treesitter Symbols',
+ finder = finders.new_table {
+ results = results,
+ entry_maker = make_entry.gen_from_treesitter(opts)
+ },
+ previewer = previewers.vimgrep.new(opts),
+ sorter = conf.generic_sorter(opts),
+ }):find()
+end
+
+files.current_buffer_fuzzy_find = function(opts)
+ local lines = vim.api.nvim_buf_get_lines(0, 0, -1, false)
+ local lines_with_numbers = {}
+ for k, v in ipairs(lines) do
+ table.insert(lines_with_numbers, {k, v})
+ end
+
+ local bufnr = vim.api.nvim_get_current_buf()
+
+ pickers.new(opts, {
+ prompt_title = 'Current Buffer Fuzzy',
+ finder = finders.new_table {
+ results = lines_with_numbers,
+ entry_maker = function(enumerated_line)
+ return {
+ bufnr = bufnr,
+ display = enumerated_line[2],
+ ordinal = enumerated_line[2],
+
+ lnum = enumerated_line[1],
+ }
+ end
+ },
+ sorter = conf.generic_sorter(opts),
+ attach_mappings = function()
+ actions._goto_file_selection:enhance {
+ post = function()
+ local selection = actions.get_selected_entry()
+ vim.api.nvim_win_set_cursor(0, {selection.lnum, 0})
+ end,
+ }
+
+ return true
+ end
+ }):find()
+end
+
+files.tags = function(opts)
+ local ctags_file = opts.ctags_file or 'tags'
+
+ if not vim.loop.fs_open(vim.fn.expand(ctags_file), "r", 438) then
+ print('Tags file does not exists. Create one with ctags -R')
+ return
+ end
+
+ local fd = assert(vim.loop.fs_open(vim.fn.expand(ctags_file), "r", 438))
+ local stat = assert(vim.loop.fs_fstat(fd))
+ local data = assert(vim.loop.fs_read(fd, stat.size, 0))
+ assert(vim.loop.fs_close(fd))
+
+ local results = vim.split(data, '\n')
+
+ pickers.new(opts,{
+ prompt = 'Tags',
+ finder = finders.new_table {
+ results = results,
+ entry_maker = make_entry.gen_from_ctags(opts),
+ },
+ previewer = previewers.ctags.new(opts),
+ sorter = conf.generic_sorter(opts),
+ attach_mappings = function()
+ actions._goto_file_selection:enhance {
+ post = function()
+ local selection = actions.get_selected_entry()
+
+ local scode = string.gsub(selection.scode, '[$]$', '')
+ scode = string.gsub(scode, [[\\]], [[\]])
+ scode = string.gsub(scode, [[\/]], [[/]])
+ scode = string.gsub(scode, '[*]', [[\*]])
+
+ vim.cmd('norm! gg')
+ vim.fn.search(scode)
+ vim.cmd('norm! zz')
+ end,
+ }
+ return true
+ end
+ }):find()
+end
+
+files.current_buffer_tags = function(opts)
+ return files.tags(vim.tbl_extend("force", {only_current_file = true, hide_filename = true}, opts))
+end
+
+
+local function apply_checks(mod)
+ for k, v in pairs(mod) do
+ mod[k] = function(opts)
+ opts = opts or {}
+
+ v(opts)
+ end
+ end
+
+ return mod
+end
+
+return apply_checks(files)
diff --git a/lua/telescope/builtin/init.lua b/lua/telescope/builtin/init.lua
index 9853072..f180cbe 100644
--- a/lua/telescope/builtin/init.lua
+++ b/lua/telescope/builtin/init.lua
@@ -23,1018 +23,45 @@ if 2 > vim.o.report then
vim.api.nvim_err_writeln("[telescope] If you do not, you will have a bad experience")
end
-
-local actions = require('telescope.actions')
-local finders = require('telescope.finders')
-local make_entry = require('telescope.make_entry')
-local path = require('telescope.path')
-local pickers = require('telescope.pickers')
-local previewers = require('telescope.previewers')
-local sorters = require('telescope.sorters')
-local utils = require('telescope.utils')
-
-local conf = require('telescope.config').values
-
-local filter = vim.tbl_filter
-local flatten = vim.tbl_flatten
-
local builtin = {}
+builtin.live_grep = require('telescope.builtin.files').live_grep
+builtin.grep_string = require('telescope.builtin.files').grep_string
+builtin.find_files = require('telescope.builtin.files').find_files
+builtin.fd = builtin.find_files
+builtin.treesitter = require('telescope.builtin.files').treesitter
+builtin.current_buffer_fuzzy_find = require('telescope.builtin.files').current_buffer_fuzzy_find
+builtin.tags = require('telescope.builtin.files').tags
+builtin.current_buffer_tags = require('telescope.builtin.files').current_buffer_tags
+
builtin.git_files = require('telescope.builtin.git').files
builtin.git_commits = require('telescope.builtin.git').commits
builtin.git_bcommits = require('telescope.builtin.git').bcommits
builtin.git_branches = require('telescope.builtin.git').branches
builtin.git_status = require('telescope.builtin.git').status
-builtin.commands = function()
- pickers.new({}, {
- prompt_title = 'Commands',
- finder = finders.new_table {
- results = (function()
- local command_iter = vim.api.nvim_get_commands({})
- local commands = {}
-
- for _, cmd in pairs(command_iter) do
- table.insert(commands, cmd)
- end
-
- return commands
- end)(),
- entry_maker = function(line)
- return {
- valid = line ~= "",
- value = line,
- ordinal = line.name,
- display = line.name
- }
- end
- },
- sorter = conf.generic_sorter(),
- attach_mappings = function(prompt_bufnr)
- actions.goto_file_selection_edit:replace(function()
- local selection = actions.get_selected_entry()
- actions.close(prompt_bufnr)
- local val = selection.value
- local cmd = string.format([[:%s ]], val.name)
-
- if val.nargs == "0" then
- vim.cmd(cmd)
- else
- vim.cmd [[stopinsert]]
- vim.fn.feedkeys(cmd)
- end
- end)
-
- return true
- end
- }):find()
-end
-
-builtin.live_grep = function(opts)
- opts = opts or {}
-
- 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
- return nil
- end
-
- return flatten { conf.vimgrep_arguments, prompt }
- end,
- opts.entry_maker or make_entry.gen_from_vimgrep(opts),
- opts.max_results
- )
-
- pickers.new(opts, {
- prompt_title = 'Live Grep',
- finder = live_grepper,
- previewer = previewers.vimgrep.new(opts),
- sorter = conf.generic_sorter(opts),
- }):find()
-end
-
-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()
- params.context = { includeDeclaration = true }
-
- local results_lsp = vim.lsp.buf_request_sync(0, "textDocument/references", params, opts.timeout or 10000)
- local locations = {}
- for _, server_results in pairs(results_lsp) do
- if server_results.result then
- vim.list_extend(locations, vim.lsp.util.locations_to_items(server_results.result) or {})
- end
- end
-
- if vim.tbl_isempty(locations) then
- return
- end
-
- pickers.new(opts, {
- prompt_title = 'LSP References',
- finder = finders.new_table {
- results = locations,
- entry_maker = make_entry.gen_from_quickfix(opts),
- },
- previewer = previewers.qflist.new(opts),
- sorter = conf.generic_sorter(opts),
- }):find()
-end
-
-builtin.lsp_document_symbols = function(opts)
- opts = opts or {}
-
- local params = vim.lsp.util.make_position_params()
- local results_lsp = vim.lsp.buf_request_sync(0, "textDocument/documentSymbol", params, opts.timeout or 10000)
-
- 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_title = 'LSP Document Symbols',
- finder = finders.new_table {
- results = locations,
- entry_maker = make_entry.gen_from_quickfix(opts)
- },
- previewer = previewers.vim_buffer.new(opts),
- sorter = conf.generic_sorter(opts),
- }):find()
-end
-
-builtin.lsp_code_actions = function(opts)
- opts = opts or {}
-
- local params = vim.lsp.util.make_range_params()
-
- params.context = {
- diagnostics = vim.lsp.diagnostic.get_line_diagnostics()
- }
-
- local results_lsp, err = vim.lsp.buf_request_sync(0, "textDocument/codeAction", params, opts.timeout or 10000)
-
- if err then
- print("ERROR: " .. err)
- return
- end
-
- if not results_lsp or vim.tbl_isempty(results_lsp) then
- print("No results from textDocument/codeAction")
- return
- end
-
- local results = (results_lsp[1] or results_lsp[2]).result;
-
- if not results or #results == 0 then
- print("No code actions available")
- return
- end
-
- for i,x in ipairs(results) do
- x.idx = i
- end
-
- pickers.new(opts, {
- prompt_title = 'LSP Code Actions',
- finder = finders.new_table {
- results = results,
- entry_maker = function(line)
- return {
- valid = line ~= nil,
- value = line,
- ordinal = line.idx .. line.title,
- display = line.idx .. ': ' .. line.title
- }
- end
- },
- attach_mappings = function(prompt_bufnr)
- actions.goto_file_selection_edit:replace(function()
- local selection = actions.get_selected_entry()
- actions.close(prompt_bufnr)
- local val = selection.value
-
- if val.edit or type(val.command) == "table" then
- if val.edit then
- vim.lsp.util.apply_workspace_edit(val.edit)
- end
- if type(val.command) == "table" then
- vim.lsp.buf.execute_command(val.command)
- end
- else
- vim.lsp.buf.execute_command(val)
- end
- end)
-
- return true
- end,
- sorter = conf.generic_sorter(opts),
- }):find()
-end
-
-builtin.lsp_workspace_symbols = function(opts)
- opts = opts or {}
- opts.shorten_path = utils.get_default(opts.shorten_path, true)
-
- local params = {query = opts.query or ''}
- local results_lsp = vim.lsp.buf_request_sync(0, "workspace/symbol", params, opts.timeout or 10000)
-
- if not results_lsp or vim.tbl_isempty(results_lsp) then
- print("No results from workspace/symbol")
- return
- end
-
- local locations = {}
- for _, server_results in pairs(results_lsp) do
- if server_results.result then
- vim.list_extend(locations, vim.lsp.util.symbols_to_items(server_results.result, 0) or {})
- end
- end
-
- if vim.tbl_isempty(locations) then
- return
- end
-
- pickers.new(opts, {
- prompt_title = 'LSP Workspace Symbols',
- finder = finders.new_table {
- results = locations,
- entry_maker = make_entry.gen_from_quickfix(opts)
- },
- previewer = previewers.qflist.new(opts),
- sorter = conf.generic_sorter(opts),
- }):find()
-end
-
-builtin.quickfix = function(opts)
- opts = opts or {}
-
- local locations = vim.fn.getqflist()
-
- if vim.tbl_isempty(locations) then
- return
- end
-
- pickers.new(opts, {
- prompt_title = 'Quickfix',
- finder = finders.new_table {
- results = locations,
- entry_maker = make_entry.gen_from_quickfix(opts),
- },
- previewer = previewers.qflist.new(opts),
- sorter = conf.generic_sorter(opts),
- }):find()
-end
-
-builtin.loclist = function(opts)
- local locations = vim.fn.getloclist(0)
- local filename = vim.api.nvim_buf_get_name(0)
-
- for _, value in pairs(locations) do
- value.filename = filename
- end
-
- if vim.tbl_isempty(locations) then
- return
- end
-
- pickers.new(opts, {
- prompt_title = 'Loclist',
- finder = finders.new_table {
- results = locations,
- entry_maker = make_entry.gen_from_quickfix(opts),
- },
- previewer = previewers.qflist.new(opts),
- sorter = conf.generic_sorter(opts),
- }):find()
-end
-
--- Special keys:
--- opts.search -- the string to search.
-builtin.grep_string = function(opts)
- opts = opts or {}
-
- -- TODO: This should probably check your visual selection as well, if you've got one
- local search = opts.search or vim.fn.expand("<cword>")
-
- opts.entry_maker = opts.entry_maker or make_entry.gen_from_vimgrep(opts)
- opts.word_match = opts.word_match or nil
-
- pickers.new(opts, {
- prompt_title = 'Find Word',
- finder = finders.new_oneshot_job(
- flatten { conf.vimgrep_arguments, opts.word_match, search},
- opts
- ),
- previewer = previewers.vimgrep.new(opts),
- sorter = conf.generic_sorter(opts),
- }):find()
-end
-
-builtin.oldfiles = function(opts)
- opts = opts or {}
-
- pickers.new(opts, {
- prompt_title = 'Oldfiles',
- finder = finders.new_table(vim.tbl_filter(function(val)
- return 0 ~= vim.fn.filereadable(val)
- end, vim.v.oldfiles)),
- sorter = conf.file_sorter(opts),
- previewer = previewers.cat.new(opts),
- }):find()
-end
-
-builtin.command_history = function(opts)
- local history_string = vim.fn.execute('history cmd')
- local history_list = vim.split(history_string, "\n")
-
- local results = {}
- for i = #history_list, 3, -1 do
- local item = history_list[i]
- local _, finish = string.find(item, "%d+ +")
- table.insert(results, string.sub(item, finish + 1))
- end
-
- pickers.new(opts, {
- prompt_title = 'Command History',
- finder = finders.new_table(results),
- sorter = sorters.fuzzy_with_index_bias(),
-
- attach_mappings = function(_, map)
- map('i', '<CR>', actions.set_command_line)
-
- -- TODO: Find a way to insert the text... it seems hard.
- -- map('i', '<C-i>', actions.insert_value, { expr = true })
-
- return true
- end,
- }):find()
-end
-
-builtin.vim_options = function(opts)
- opts = opts or {}
-
- -- Load vim options.
- local vim_opts = loadfile(utils.data_directory() .. path.separator .. 'options' .. path.separator .. 'options.lua')().options
-
- pickers.new(opts, {
- prompt = 'options',
- finder = finders.new_table {
- results = vim_opts,
- entry_maker = make_entry.gen_from_vimoptions(opts),
- },
- -- TODO: previewer for Vim options
- -- previewer = previewers.help.new(opts),
- sorter = sorters.get_fzy_sorter(),
- attach_mappings = function(prompt_bufnr)
- actions.goto_file_selection_edit:replace(function()
- local selection = actions.get_selected_entry()
- local esc = ""
-
- if vim.fn.mode() == "i" then
- -- TODO: don't make this local
- esc = vim.api.nvim_replace_termcodes("<esc>", true, false, true)
- end
-
- -- TODO: Make this actually work.
-
- -- actions.close(prompt_bufnr)
- -- vim.api.nvim_win_set_var(vim.fn.nvim_get_current_win(), "telescope", 1)
- -- print(prompt_bufnr)
- -- print(vim.fn.bufnr())
- -- vim.cmd([[ autocmd BufEnter <buffer> ++nested ++once startinsert!]])
- -- print(vim.fn.winheight(0))
-
- -- local prompt_winnr = vim.fn.getbufinfo(prompt_bufnr)[1].windows[1]
- -- print(prompt_winnr)
-
- -- local float_opts = {}
- -- float_opts.relative = "editor"
- -- float_opts.anchor = "sw"
- -- float_opts.focusable = false
- -- float_opts.style = "minimal"
- -- float_opts.row = vim.api.nvim_get_option("lines") - 2 -- TODO: include `cmdheight` and `laststatus` in this calculation
- -- float_opts.col = 2
- -- float_opts.height = 10
- -- float_opts.width = string.len(selection.last_set_from)+15
- -- local buf = vim.fn.nvim_create_buf(false, true)
- -- vim.fn.nvim_buf_set_lines(buf, 0, 0, false, {"default value: abcdef", "last set from: " .. selection.last_set_from})
- -- local status_win = vim.fn.nvim_open_win(buf, false, float_opts)
- -- -- vim.api.nvim_win_set_option(status_win, "winblend", 100)
- -- vim.api.nvim_win_set_option(status_win, "winhl", "Normal:PmenuSel")
- -- -- vim.api.nvim_set_current_win(status_win)
- -- vim.cmd[[redraw!]]
- -- vim.cmd("autocmd CmdLineLeave : ++once echom 'beep'")
- vim.api.nvim_feedkeys(string.format("%s:set %s=%s", esc, selection.name, selection.current_value), "m", true)
- end)
-
- return true
- end
- }):find()
-end
-
-builtin.help_tags = function(opts)
- opts = opts or {}
-
- local tags = {}
- for _, file in pairs(vim.fn.findfile('doc/tags', vim.o.runtimepath, -1)) do
- local f = assert(io.open(file, "rb"))
- for line in f:lines() do
- table.insert(tags, line)
- end
- f:close()
- end
-
- pickers.new(opts, {
- prompt_title = 'Help',
- finder = finders.new_table {
- results = tags,
- entry_maker = make_entry.gen_from_taglist(opts),
- },
- -- TODO: previewer for Vim help
- previewer = previewers.help.new(opts),
- sorter = conf.generic_sorter(opts),
- attach_mappings = function(prompt_bufnr)
- actions._goto_file_selection:replace(function(_, cmd)
- local selection = actions.get_selected_entry()
- actions.close(prompt_bufnr)
- if cmd == 'edit' or cmd == 'new' then
- vim.cmd('help ' .. selection.value)
- elseif cmd == 'vnew' then
- vim.cmd('vert bo help ' .. selection.value)
- elseif cmd == 'tabedit' then
- vim.cmd('tab help ' .. selection.value)
- end
- end)
-
- return true
- end
- }):find()
-end
-
-builtin.reloader = function(opts)
- opts = opts or {}
- local package_list = vim.tbl_keys(package.loaded)
-
- -- filter out packages we don't want and track the longest package name
- opts.column_len = 0
- for index, module_name in pairs(package_list) do
- if type(require(module_name)) ~= 'table' or module_name:sub(1,1) == "_" or package.searchpath(module_name, package.path) == nil then
- table.remove(package_list, index)
- elseif #module_name > opts.column_len then
- opts.column_len = #module_name
- end
- end
-
- pickers.new(opts, {
- prompt_title = 'Packages',
- finder = finders.new_table {
- results = package_list,
- entry_maker = make_entry.gen_from_packages(opts),
- },
- -- previewer = previewers.vim_buffer.new(opts),
- sorter = conf.generic_sorter(opts),
-
- attach_mappings = function(prompt_bufnr)
- actions.goto_file_selection_edit:replace(function()
- local selection = actions.get_selected_entry()
-
- actions.close(prompt_bufnr)
- require('plenary.reload').reload_module(selection.value)
- print(string.format("[%s] - module reloaded", selection.value))
- end)
-
- return true
- end
- }):find()
-end
-
--- TODO: What the heck should we do for accepting this.
--- vim.fn.setreg("+", "nnoremap $TODO :lua require('telescope.builtin').<whatever>()<CR>")
--- TODO: Can we just do the names instead?
-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 = {}
-
- for k, v in pairs(builtin) do
- local debug_info = debug.getinfo(v)
-
- table.insert(objs, {
- filename = string.sub(debug_info.source, 2),
- lnum = debug_info.linedefined,
- col = 0,
- text = k,
-
- start = debug_info.linedefined,
- finish = debug_info.lastlinedefined,
- })
- end
-
- pickers.new(opts, {
- prompt_title = 'Telescope Builtin',
- finder = finders.new_table {
- results = objs,
- entry_maker = make_entry.gen_from_quickfix(opts),
- },
- previewer = previewers.qflist.new(opts),
- sorter = conf.generic_sorter(opts),
- attach_mappings = function(_)
- actions.goto_file_selection_edit:replace(actions.run_builtin)
- return true
- end
- }):find()
-end
-
-
--- TODO: Maybe just change this to `find`.
--- Support `find` and maybe let people do other stuff with it as well.
-builtin.find_files = function(opts)
- opts = opts or {}
-
- local find_command = opts.find_command
-
- if not find_command then
- if 1 == vim.fn.executable("fd") then
- find_command = { 'fd', '--type', 'f' }
- elseif 1 == vim.fn.executable("fdfind") then
- find_command = { 'fdfind', '--type', 'f' }
- elseif 1 == vim.fn.executable("rg") then
- find_command = { 'rg', '--files' }
- elseif 1 == vim.fn.executable("find") then
- find_command = { 'find', '.', '-type', 'f' }
- end
- end
-
- if not find_command then
- print("You need to install either find, fd, or rg. You can also submit a PR to add support for another file finder :)")
- return
- end
-
- if opts.cwd then
- opts.cwd = vim.fn.expand(opts.cwd)
- end
-
- opts.entry_maker = opts.entry_maker or make_entry.gen_from_file(opts)
-
- pickers.new(opts, {
- prompt_title = 'Find Files',
- finder = finders.new_oneshot_job(
- find_command,
- opts
- ),
- previewer = previewers.cat.new(opts),
- sorter = conf.file_sorter(opts),
- }):find()
-end
-
--- Leave this alias around for people.
-builtin.fd = builtin.find_files
-
--- TODO: I'd like to use the `vim_buffer` previewer, but it doesn't seem to work due to some styling problems.
--- I think it has something to do with nvim_open_win and style='minimal',
--- Status, currently operational.
-builtin.buffers = function(opts)
- opts = opts or {}
-
- local bufnrs = filter(function(b)
- return
- (opts.show_all_buffers
- or vim.api.nvim_buf_is_loaded(b))
- and 1 == vim.fn.buflisted(b)
- end, vim.api.nvim_list_bufs())
-
- local buffers = {}
- local default_selection_idx = 1
- for _, bufnr in ipairs(bufnrs) do
- local flag = bufnr == vim.fn.bufnr('') and '%' or (bufnr == vim.fn.bufnr('#') and '#' or ' ')
-
- if opts.sort_lastused and flag == "#" then
- default_selection_idx = 2
- end
-
- local element = {
- bufnr = bufnr,
- flag = flag,
- info = vim.fn.getbufinfo(bufnr)[1],
- }
-
- if opts.sort_lastused and (flag == "#" or flag == "%") then
- local idx = ((buffers[1] ~= nil and buffers[1].flag == "%") and 2 or 1)
- table.insert(buffers, idx, element)
- else
- table.insert(buffers, element)
- end
- end
-
- if not opts.bufnr_width then
- local max_bufnr = math.max(unpack(bufnrs))
- opts.bufnr_width = #tostring(max_bufnr)
- end
-
- pickers.new(opts, {
- prompt_title = 'Buffers',
- finder = finders.new_table {
- results = buffers,
- entry_maker = make_entry.gen_from_buffer(opts)
- },
- previewer = previewers.vim_buffer.new(opts),
- sorter = conf.generic_sorter(opts),
- default_selection_index = default_selection_idx,
- }):find()
-end
-
-local function prepare_match(entry, kind)
- local entries = {}
-
- if entry.node then
- entry["kind"] = kind
- table.insert(entries, entry)
- else
- for name, item in pairs(entry) do
- vim.list_extend(entries, prepare_match(item, name))
- end
- end
-
- return entries
-end
-
-builtin.treesitter = function(opts)
- opts = opts or {}
-
- opts.show_line = utils.get_default(opts.show_line, true)
-
- local has_nvim_treesitter, _ = pcall(require, 'nvim-treesitter')
- if not has_nvim_treesitter then
- print('You need to install nvim-treesitter')
- return
- end
-
- local parsers = require('nvim-treesitter.parsers')
- if not parsers.has_parser() then
- print('No parser for the current buffer')
- return
- end
-
- local ts_locals = require('nvim-treesitter.locals')
- local bufnr = opts.bufnr or vim.api.nvim_get_current_buf()
-
- local results = {}
- for _, definitions in ipairs(ts_locals.get_definitions(bufnr)) do
- local entries = prepare_match(definitions)
- for _, entry in ipairs(entries) do
- table.insert(results, entry)
- end
- end
-
- if vim.tbl_isempty(results) then
- return
- end
-
- pickers.new(opts, {
- prompt_title = 'Treesitter Symbols',
- finder = finders.new_table {
- results = results,
- entry_maker = make_entry.gen_from_treesitter(opts)
- },
- previewer = previewers.vim_buffer.new(opts),
- sorter = conf.generic_sorter(opts),
- }):find()
-end
-
-builtin.planets = function(opts)
- opts = opts or {}
- local show_pluto = opts.show_pluto or false
-
- local sourced_file = require('plenary.debug_utils').sourced_filepath()
- local base_directory = vim.fn.fnamemodify(sourced_file, ":h:h:h")
-
- local globbed_files = vim.fn.globpath(base_directory .. '/data/memes/planets/', '*', true, true)
- local acceptable_files = {}
- for _, v in ipairs(globbed_files) do
- if not show_pluto and v:find("pluto") then
- else
- table.insert(acceptable_files,vim.fn.fnamemodify(v, ':t'))
- end
- end
-
- pickers.new {
- prompt_title = 'Planets',
- finder = finders.new_table {
- results = acceptable_files,
- entry_maker = function(line)
- return {
- ordinal = line,
- display = line,
- filename = base_directory .. '/data/memes/planets/' .. line,
- }
- end
- },
- previewer = previewers.cat.new(opts),
- sorter = conf.generic_sorter(opts),
- attach_mappings = function(prompt_bufnr)
- actions.goto_file_selection_edit:replace(function()
- local selection = actions.get_selected_entry()
- actions.close(prompt_bufnr)
-
- print("Enjoy astronomy! You viewed:", selection.display)
- end)
-
- return true
- end,
- }:find()
-end
-
-builtin.current_buffer_fuzzy_find = function(opts)
- local lines = vim.api.nvim_buf_get_lines(0, 0, -1, false)
- local lines_with_numbers = {}
- for k, v in ipairs(lines) do
- table.insert(lines_with_numbers, {k, v})
- end
-
- local bufnr = vim.api.nvim_get_current_buf()
-
- pickers.new(opts, {
- prompt_title = 'Current Buffer Fuzzy',
- finder = finders.new_table {
- results = lines_with_numbers,
- entry_maker = function(enumerated_line)
- return {
- bufnr = bufnr,
- display = enumerated_line[2],
- ordinal = enumerated_line[2],
-
- lnum = enumerated_line[1],
- }
- end
- },
- sorter = sorters.get_generic_fuzzy_sorter(),
- attach_mappings = function()
- actions._goto_file_selection:enhance {
- post = function()
- local selection = actions.get_selected_entry()
- vim.api.nvim_win_set_cursor(0, {selection.lnum, 0})
- end,
- }
-
- return true
- end
- }):find()
-end
-
-builtin.man_pages = function(opts)
- opts = opts or {}
-
- local cmd = opts.man_cmd or "apropos --sections=1 ''"
-
- local pages = utils.get_os_command_output(cmd)
-
- local lines = {}
- for s in pages:gmatch("[^\r\n]+") do
- table.insert(lines, s)
- end
-
- pickers.new(opts, {
- prompt_title = 'Man',
- finder = finders.new_table {
- results = lines,
- entry_maker = make_entry.gen_from_apropos(opts),
- },
- previewer = previewers.man.new(opts),
- sorter = sorters.get_generic_fuzzy_sorter(),
- attach_mappings = function(prompt_bufnr)
- actions._goto_file_selection:replace(function(_, cmd)
- local selection = actions.get_selected_entry()
-
- actions.close(prompt_bufnr)
- if cmd == 'edit' or cmd == 'new' then
- vim.cmd('Man ' .. selection.value)
- elseif cmd == 'vnew' then
- vim.cmd('vert bo Man ' .. selection.value)
- elseif cmd == 'tabedit' then
- vim.cmd('tab Man ' .. selection.value)
- end
- end)
-
- return true
- end
- }):find()
-end
-
-builtin.colorscheme = function(opts)
- opts = opts or {}
-
- local colors = vim.list_extend(opts.colors or {}, vim.fn.getcompletion('', 'color'))
-
- pickers.new(opts,{
- prompt = 'Change Colorscheme',
- finder = finders.new_table {
- results = colors
- },
- -- TODO: better preview?
- sorter = sorters.get_generic_fuzzy_sorter(),
- attach_mappings = function(prompt_bufnr)
- actions.goto_file_selection_edit:replace(function()
- local selection = actions.get_selected_entry()
-
- actions.close(prompt_bufnr)
- vim.cmd("colorscheme " .. selection.value)
- end)
-
- return true
- end
- }):find()
-end
-
-builtin.marks = function(opts)
- opts = opts or {}
-
- local marks = vim.api.nvim_exec("marks", true)
- local marks_table = vim.fn.split(marks, "\n")
-
- -- Pop off the header.
- table.remove(marks_table, 1)
-
- pickers.new(opts,{
- prompt = 'Marks',
- finder = finders.new_table {
- results = marks_table,
- entry_maker = make_entry.gen_from_marks(opts),
- },
- previewer = previewers.vimgrep.new(opts),
- sorter = sorters.get_generic_fuzzy_sorter(),
- }):find()
-end
-
-builtin.registers = function(opts)
- opts = opts or {}
-
- local registers_table = {"\"", "_", "#", "=", "_", "/", "*", "+", ":", ".", "%"}
-
- -- named
- for i = 0, 9 do
- table.insert(registers_table, tostring(i))
- end
-
- -- alphabetical
- for i = 65, 90 do
- table.insert(registers_table, string.char(i))
- end
-
- pickers.new(opts,{
- prompt_title = 'Registers',
- finder = finders.new_table {
- results = registers_table,
- entry_maker = make_entry.gen_from_registers(opts),
- },
- -- use levenshtein as n-gram doesn't support <2 char matches
- sorter = sorters.get_levenshtein_sorter(),
- attach_mappings = function(_, map)
- map('i', '<CR>', actions.paste_register)
- map('i', '<C-e>', actions.edit_register)
-
- return true
- end,
- }):find()
-end
-
--- find normal mode mappings
-builtin.keymaps = function(opts)
- opts = opts or {}
- local modes = {"n", "i", "c"}
- local keymaps_table = {}
- for _, mode in pairs(modes) do
- local keymaps_iter = vim.api.nvim_get_keymap(mode)
- for _, keymap in pairs(keymaps_iter) do
- table.insert(keymaps_table, keymap)
- end
- end
-
- pickers.new({}, {
- prompt_title = 'Key Maps',
- finder = finders.new_table {
- results = keymaps_table,
- entry_maker = function(line)
- return {
- valid = line ~= "",
- value = line,
- ordinal = line.lhs .. line.rhs,
- display = line.mode .. ' ' .. utils.display_termcodes(line.lhs) .. ' ' .. line.rhs
- }
- end
- },
- sorter = conf.generic_sorter()
- }):find()
-end
-
-builtin.filetypes = function(opts)
- opts = opts or {}
-
- local filetypes = vim.fn.getcompletion('', 'filetype')
-
- pickers.new({}, {
- prompt_title = 'Filetypes',
- finder = finders.new_table {
- results = filetypes,
- },
- sorter = conf.generic_sorter(),
- attach_mappings = function(prompt_bufnr)
- actions.goto_file_selection_edit:replace(function()
- local selection = actions.get_selected_entry()
- actions.close(prompt_bufnr)
- vim.cmd('setfiletype ' .. selection[1])
- end)
- return true
- end
- }):find()
-end
-
-builtin.highlights = function(opts)
- opts = opts or {}
-
- local highlights = vim.fn.getcompletion('', 'highlight')
-
- pickers.new({}, {
- prompt_title = 'Highlights',
- finder = finders.new_table {
- results = highlights,
- entry_maker = make_entry.gen_from_highlights(opts)
- },
- sorter = conf.generic_sorter(),
- attach_mappings = function(prompt_bufnr)
- actions.goto_file_selection_edit:replace(function()
- local selection = actions.get_selected_entry()
- actions.close(prompt_bufnr)
- vim.cmd('hi ' .. selection.value)
- end)
- return true
- end,
- previewer = previewers.display_content.new(opts),
- }):find()
-end
-
-builtin.tags = function(opts)
- opts = opts or {}
-
- local ctags_file = opts.ctags_file or 'tags'
-
- if not vim.loop.fs_open(vim.fn.expand(ctags_file), "r", 438) then
- print('Tags file does not exists. Create one with ctags -R')
- return
- end
-
- local fd = assert(vim.loop.fs_open(vim.fn.expand(ctags_file), "r", 438))
- local stat = assert(vim.loop.fs_fstat(fd))
- local data = assert(vim.loop.fs_read(fd, stat.size, 0))
- assert(vim.loop.fs_close(fd))
-
- local results = vim.split(data, '\n')
-
- pickers.new(opts,{
- prompt = 'Tags',
- finder = finders.new_table {
- results = results,
- entry_maker = make_entry.gen_from_ctags(opts),
- },
- previewer = previewers.ctags.new(opts),
- sorter = conf.generic_sorter(opts),
- attach_mappings = function()
- actions._goto_file_selection:enhance {
- post = function()
- local selection = actions.get_selected_entry()
-
- local scode = string.gsub(selection.scode, '[$]$', '')
- scode = string.gsub(scode, [[\\]], [[\]])
- scode = string.gsub(scode, [[\/]], [[/]])
- scode = string.gsub(scode, '[*]', [[\*]])
-
- vim.cmd('norm! gg')
- vim.fn.search(scode)
- vim.cmd('norm! zz')
- end,
- }
- return true
- end
- }):find()
-end
-
-builtin.current_buffer_tags = function(opts)
- opts = opts or {}
- return builtin.tags(vim.tbl_extend("force", {only_current_file = true, hide_filename = true}, opts))
-end
+builtin.builtin = require('telescope.builtin.internal').builtin
+builtin.planets = require('telescope.builtin.internal').planets
+builtin.commands = require('telescope.builtin.internal').commands
+builtin.quickfix = require('telescope.builtin.internal').quickfix
+builtin.loclist = require('telescope.builtin.internal').loclist
+builtin.oldfiles = require('telescope.builtin.internal').oldfiles
+builtin.command_history = require('telescope.builtin.internal').command_history
+builtin.vim_options = require('telescope.builtin.internal').vim_options
+builtin.help_tags = require('telescope.builtin.internal').help_tags
+builtin.man_pages = require('telescope.builtin.internal').man_pages
+builtin.reloader = require('telescope.builtin.internal').reloader
+builtin.buffers = require('telescope.builtin.internal').buffers
+builtin.colorscheme = require('telescope.builtin.internal').colorscheme
+builtin.marks = require('telescope.builtin.internal').marks
+builtin.registers = require('telescope.builtin.internal').registers
+builtin.keymaps = require('telescope.builtin.internal').keymaps
+builtin.filetypes = require('telescope.builtin.internal').filetypes
+builtin.highlights = require('telescope.builtin.internal').highlights
+
+builtin.lsp_references = require('telescope.builtin.lsp').references
+builtin.lsp_document_symbols = require('telescope.builtin.lsp').document_symbols
+builtin.lsp_code_actions = require('telescope.builtin.lsp').code_actions
+builtin.lsp_workspace_symbols = require('telescope.builtin.lsp').workspace_symbols
return builtin
diff --git a/lua/telescope/builtin/internal.lua b/lua/telescope/builtin/internal.lua
new file mode 100644
index 0000000..76bc969
--- /dev/null
+++ b/lua/telescope/builtin/internal.lua
@@ -0,0 +1,595 @@
+local actions = require('telescope.actions')
+local finders = require('telescope.finders')
+local make_entry = require('telescope.make_entry')
+local path = require('telescope.path')
+local pickers = require('telescope.pickers')
+local previewers = require('telescope.previewers')
+local sorters = require('telescope.sorters')
+local utils = require('telescope.utils')
+
+local conf = require('telescope.config').values
+
+local filter = vim.tbl_filter
+
+local internal = {}
+
+-- TODO: What the heck should we do for accepting this.
+-- vim.fn.setreg("+", "nnoremap $TODO :lua require('telescope.builtin').<whatever>()<CR>")
+-- TODO: Can we just do the names instead?
+internal.builtin = function(opts)
+ opts.hide_filename = utils.get_default(opts.hide_filename, true)
+ opts.ignore_filename = utils.get_default(opts.ignore_filename, true)
+
+ local objs = {}
+
+ local modules = {
+ require('telescope.builtin.internal'),
+ require('telescope.builtin.git'),
+ require('telescope.builtin.lsp'),
+ require('telescope.builtin.files'),
+ }
+
+ for _, m in ipairs(modules) do
+ for k, v in pairs(m) do
+ local debug_info = debug.getinfo(v)
+
+ table.insert(objs, {
+ filename = string.sub(debug_info.source, 2),
+ text = k,
+ })
+ end
+ end
+
+ pickers.new(opts, {
+ prompt_title = 'Telescope Builtin',
+ finder = finders.new_table {
+ results = objs,
+ entry_maker = make_entry.gen_from_quickfix(opts),
+ },
+ previewer = previewers.builtin.new(opts),
+ sorter = conf.generic_sorter(opts),
+ attach_mappings = function(_)
+ actions.goto_file_selection_edit:replace(actions.run_builtin)
+ return true
+ end
+ }):find()
+end
+
+internal.planets = function(opts)
+ local show_pluto = opts.show_pluto or false
+
+ local sourced_file = require('plenary.debug_utils').sourced_filepath()
+ local base_directory = vim.fn.fnamemodify(sourced_file, ":h:h:h:h")
+
+ local globbed_files = vim.fn.globpath(base_directory .. '/data/memes/planets/', '*', true, true)
+ local acceptable_files = {}
+ for _, v in ipairs(globbed_files) do
+ if not show_pluto and v:find("pluto") then
+ else
+ table.insert(acceptable_files,vim.fn.fnamemodify(v, ':t'))
+ end
+ end
+
+ pickers.new {
+ prompt_title = 'Planets',
+ finder = finders.new_table {
+ results = acceptable_files,
+ entry_maker = function(line)
+ return {
+ ordinal = line,
+ display = line,
+ filename = base_directory .. '/data/memes/planets/' .. line,
+ }
+ end
+ },
+ previewer = previewers.cat.new(opts),
+ sorter = conf.generic_sorter(opts),
+ attach_mappings = function(prompt_bufnr)
+ actions.goto_file_selection_edit:replace(function()
+ local selection = actions.get_selected_entry()
+ actions.close(prompt_bufnr)
+
+ print("Enjoy astronomy! You viewed:", selection.display)
+ end)
+
+ return true
+ end,
+ }:find()
+end
+
+internal.commands = function(opts)
+ pickers.new({}, {
+ prompt_title = 'Commands',
+ finder = finders.new_table {
+ results = (function()
+ local command_iter = vim.api.nvim_get_commands({})
+ local commands = {}
+
+ for _, cmd in pairs(command_iter) do
+ table.insert(commands, cmd)
+ end
+
+ return commands
+ end)(),
+ entry_maker = function(line)
+ return {
+ valid = line ~= "",
+ value = line,
+ ordinal = line.name,
+ display = line.name
+ }
+ end
+ },
+ sorter = conf.generic_sorter(opts),
+ attach_mappings = function(prompt_bufnr)
+ actions.goto_file_selection_edit:replace(function()
+ local selection = actions.get_selected_entry()
+ actions.close(prompt_bufnr)
+ local val = selection.value
+ local cmd = string.format([[:%s ]], val.name)
+
+ if val.nargs == "0" then
+ vim.cmd(cmd)
+ else
+ vim.cmd [[stopinsert]]
+ vim.fn.feedkeys(cmd)
+ end
+ end)
+
+ return true
+ end
+ }):find()
+end
+
+internal.quickfix = function(opts)
+ local locations = vim.fn.getqflist()
+
+ if vim.tbl_isempty(locations) then
+ return
+ end
+
+ pickers.new(opts, {
+ prompt_title = 'Quickfix',
+ finder = finders.new_table {
+ results = locations,
+ entry_maker = make_entry.gen_from_quickfix(opts),
+ },
+ previewer = previewers.qflist.new(opts),
+ sorter = conf.generic_sorter(opts),
+ }):find()
+end
+
+internal.loclist = function(opts)
+ local locations = vim.fn.getloclist(0)
+ local filename = vim.api.nvim_buf_get_name(0)
+
+ for _, value in pairs(locations) do
+ value.filename = filename
+ end
+
+ if vim.tbl_isempty(locations) then
+ return
+ end
+
+ pickers.new(opts, {
+ prompt_title = 'Loclist',
+ finder = finders.new_table {
+ results = locations,
+ entry_maker = make_entry.gen_from_quickfix(opts),
+ },
+ previewer = previewers.qflist.new(opts),
+ sorter = conf.generic_sorter(opts),
+ }):find()
+end
+
+internal.oldfiles = function(opts)
+ pickers.new(opts, {
+ prompt_title = 'Oldfiles',
+ finder = finders.new_table(vim.tbl_filter(function(val)
+ return 0 ~= vim.fn.filereadable(val)
+ end, vim.v.oldfiles)),
+ sorter = conf.file_sorter(opts),
+ previewer = previewers.cat.new(opts),
+ }):find()
+end
+
+internal.command_history = function(opts)
+ local history_string = vim.fn.execute('history cmd')
+ local history_list = vim.split(history_string, "\n")
+
+ local results = {}
+ for i = #history_list, 3, -1 do
+ local item = history_list[i]
+ local _, finish = string.find(item, "%d+ +")
+ table.insert(results, string.sub(item, finish + 1))
+ end
+
+ pickers.new(opts, {
+ prompt_title = 'Command History',
+ finder = finders.new_table(results),
+ sorter = conf.generic_sorter(opts),
+
+ attach_mappings = function(_, map)
+ map('i', '<CR>', actions.set_command_line)
+
+ -- TODO: Find a way to insert the text... it seems hard.
+ -- map('i', '<C-i>', actions.insert_value, { expr = true })
+
+ return true
+ end,
+ }):find()
+end
+
+internal.vim_options = function(opts)
+ -- Load vim options.
+ local vim_opts = loadfile(utils.data_directory() .. path.separator .. 'options' .. path.separator .. 'options.lua')().options
+
+ pickers.new(opts, {
+ prompt = 'options',
+ finder = finders.new_table {
+ results = vim_opts,
+ entry_maker = make_entry.gen_from_vimoptions(opts),
+ },
+ -- TODO: previewer for Vim options
+ -- previewer = previewers.help.new(opts),
+ sorter = conf.generic_sorter(opts),
+ attach_mappings = function()
+ actions.goto_file_selection_edit:replace(function()
+ local selection = actions.get_selected_entry()
+ local esc = ""
+
+ if vim.fn.mode() == "i" then
+ -- TODO: don't make this local
+ esc = vim.api.nvim_replace_termcodes("<esc>", true, false, true)
+ end
+
+ -- TODO: Make this actually work.
+
+ -- actions.close(prompt_bufnr)
+ -- vim.api.nvim_win_set_var(vim.fn.nvim_get_current_win(), "telescope", 1)
+ -- print(prompt_bufnr)
+ -- print(vim.fn.bufnr())
+ -- vim.cmd([[ autocmd BufEnter <buffer> ++nested ++once startinsert!]])
+ -- print(vim.fn.winheight(0))
+
+ -- local prompt_winnr = vim.fn.getbufinfo(prompt_bufnr)[1].windows[1]
+ -- print(prompt_winnr)
+
+ -- local float_opts = {}
+ -- float_opts.relative = "editor"
+ -- float_opts.anchor = "sw"
+ -- float_opts.focusable = false
+ -- float_opts.style = "minimal"
+ -- float_opts.row = vim.api.nvim_get_option("lines") - 2 -- TODO: include `cmdheight` and `laststatus` in this calculation
+ -- float_opts.col = 2
+ -- float_opts.height = 10
+ -- float_opts.width = string.len(selection.last_set_from)+15
+ -- local buf = vim.fn.nvim_create_buf(false, true)
+ -- vim.fn.nvim_buf_set_lines(buf, 0, 0, false, {"default value: abcdef", "last set from: " .. selection.last_set_from})
+ -- local status_win = vim.fn.nvim_open_win(buf, false, float_opts)
+ -- -- vim.api.nvim_win_set_option(status_win, "winblend", 100)
+ -- vim.api.nvim_win_set_option(status_win, "winhl", "Normal:PmenuSel")
+ -- -- vim.api.nvim_set_current_win(status_win)
+ -- vim.cmd[[redraw!]]
+ -- vim.cmd("autocmd CmdLineLeave : ++once echom 'beep'")
+ vim.api.nvim_feedkeys(string.format("%s:set %s=%s", esc, selection.name, selection.current_value), "m", true)
+ end)
+
+ return true
+ end
+ }):find()
+end
+
+internal.help_tags = function(opts)
+ local tags = {}
+ for _, file in pairs(vim.fn.findfile('doc/tags', vim.o.runtimepath, -1)) do
+ local f = assert(io.open(file, "rb"))
+ for line in f:lines() do
+ table.insert(tags, line)
+ end
+ f:close()
+ end
+
+ pickers.new(opts, {
+ prompt_title = 'Help',
+ finder = finders.new_table {
+ results = tags,
+ entry_maker = make_entry.gen_from_taglist(opts),
+ },
+ -- TODO: previewer for Vim help
+ previewer = previewers.help.new(opts),
+ sorter = conf.generic_sorter(opts),
+ attach_mappings = function(prompt_bufnr)
+ actions._goto_file_selection:replace(function(_, cmd)
+ local selection = actions.get_selected_entry()
+ actions.close(prompt_bufnr)
+ if cmd == 'edit' or cmd == 'new' then
+ vim.cmd('help ' .. selection.value)
+ elseif cmd == 'vnew' then
+ vim.cmd('vert bo help ' .. selection.value)
+ elseif cmd == 'tabedit' then
+ vim.cmd('tab help ' .. selection.value)
+ end
+ end)
+
+ return true
+ end
+ }):find()
+end
+
+internal.man_pages = function(opts)
+ local cmd = opts.man_cmd or "apropos --sections=1 ''"
+
+ local pages = utils.get_os_command_output(cmd)
+
+ local lines = {}
+ for s in pages:gmatch("[^\r\n]+") do
+ table.insert(lines, s)
+ end
+
+ pickers.new(opts, {
+ prompt_title = 'Man',
+ finder = finders.new_table {
+ results = lines,
+ entry_maker = make_entry.gen_from_apropos(opts),
+ },
+ previewer = previewers.man.new(opts),
+ sorter = conf.generic_sorter(opts),
+ attach_mappings = function(prompt_bufnr)
+ actions._goto_file_selection:replace(function(_, cmd)
+ local selection = actions.get_selected_entry()
+
+ actions.close(prompt_bufnr)
+ if cmd == 'edit' or cmd == 'new' then
+ vim.cmd('Man ' .. selection.value)
+ elseif cmd == 'vnew' then
+ vim.cmd('vert bo Man ' .. selection.value)
+ elseif cmd == 'tabedit' then
+ vim.cmd('tab Man ' .. selection.value)
+ end
+ end)
+
+ return true
+ end
+ }):find()
+end
+
+internal.reloader = function(opts)
+ local package_list = vim.tbl_keys(package.loaded)
+
+ -- filter out packages we don't want and track the longest package name
+ opts.column_len = 0
+ for index, module_name in pairs(package_list) do
+ if type(require(module_name)) ~= 'table' or module_name:sub(1,1) == "_" or package.searchpath(module_name, package.path) == nil then
+ table.remove(package_list, index)
+ elseif #module_name > opts.column_len then
+ opts.column_len = #module_name
+ end
+ end
+
+ pickers.new(opts, {
+ prompt_title = 'Packages',
+ finder = finders.new_table {
+ results = package_list,
+ entry_maker = make_entry.gen_from_packages(opts),
+ },
+ -- previewer = previewers.vim_buffer.new(opts),
+ sorter = conf.generic_sorter(opts),
+
+ attach_mappings = function(prompt_bufnr)
+ actions.goto_file_selection_edit:replace(function()
+ local selection = actions.get_selected_entry()
+
+ actions.close(prompt_bufnr)
+ require('plenary.reload').reload_module(selection.value)
+ print(string.format("[%s] - module reloaded", selection.value))
+ end)
+
+ return true
+ end
+ }):find()
+end
+
+internal.buffers = function(opts)
+ local bufnrs = filter(function(b)
+ return
+ (opts.show_all_buffers
+ or vim.api.nvim_buf_is_loaded(b))
+ and 1 == vim.fn.buflisted(b)
+ end, vim.api.nvim_list_bufs())
+
+ local buffers = {}
+ local default_selection_idx = 1
+ for _, bufnr in ipairs(bufnrs) do
+ local flag = bufnr == vim.fn.bufnr('') and '%' or (bufnr == vim.fn.bufnr('#') and '#' or ' ')
+
+ if opts.sort_lastused and flag == "#" then
+ default_selection_idx = 2
+ end
+
+ local element = {
+ bufnr = bufnr,
+ flag = flag,
+ info = vim.fn.getbufinfo(bufnr)[1],
+ }
+
+ if opts.sort_lastused and (flag == "#" or flag == "%") then
+ local idx = ((buffers[1] ~= nil and buffers[1].flag == "%") and 2 or 1)
+ table.insert(buffers, idx, element)
+ else
+ table.insert(buffers, element)
+ end
+ end
+
+ if not opts.bufnr_width then
+ local max_bufnr = math.max(unpack(bufnrs))
+ opts.bufnr_width = #tostring(max_bufnr)
+ end
+
+ pickers.new(opts, {
+ prompt_title = 'Buffers',
+ finder = finders.new_table {
+ results = buffers,
+ entry_maker = make_entry.gen_from_buffer(opts)
+ },
+ previewer = previewers.vim_buffer.new(opts),
+ sorter = conf.generic_sorter(opts),
+ default_selection_index = default_selection_idx,
+ }):find()
+end
+
+internal.colorscheme = function(opts)
+ local colors = vim.list_extend(opts.colors or {}, vim.fn.getcompletion('', 'color'))
+
+ pickers.new(opts,{
+ prompt = 'Change Colorscheme',
+ finder = finders.new_table {
+ results = colors
+ },
+ -- TODO: better preview?
+ sorter = conf.generic_sorter(opts),
+ attach_mappings = function(prompt_bufnr)
+ actions.goto_file_selection_edit:replace(function()
+ local selection = actions.get_selected_entry()
+
+ actions.close(prompt_bufnr)
+ vim.cmd("colorscheme " .. selection.value)
+ end)
+
+ return true
+ end
+ }):find()
+end
+
+internal.marks = function(opts)
+ local marks = vim.api.nvim_exec("marks", true)
+ local marks_table = vim.fn.split(marks, "\n")
+
+ -- Pop off the header.
+ table.remove(marks_table, 1)
+
+ pickers.new(opts,{
+ prompt = 'Marks',
+ finder = finders.new_table {
+ results = marks_table,
+ entry_maker = make_entry.gen_from_marks(opts),
+ },
+ previewer = previewers.vimgrep.new(opts),
+ sorter = conf.generic_sorter(opts),
+ }):find()
+end
+
+internal.registers = function(opts)
+ local registers_table = {"\"", "_", "#", "=", "_", "/", "*", "+", ":", ".", "%"}
+
+ -- named
+ for i = 0, 9 do
+ table.insert(registers_table, tostring(i))
+ end
+
+ -- alphabetical
+ for i = 65, 90 do
+ table.insert(registers_table, string.char(i))
+ end
+
+ pickers.new(opts,{
+ prompt_title = 'Registers',
+ finder = finders.new_table {
+ results = registers_table,
+ entry_maker = make_entry.gen_from_registers(opts),
+ },
+ -- use levenshtein as n-gram doesn't support <2 char matches
+ sorter = sorters.get_levenshtein_sorter(),
+ attach_mappings = function(_, map)
+ actions.goto_file_selection_edit:replace(actions.paste_register)
+ map('i', '<C-e>', actions.edit_register)
+
+ return true
+ end,
+ }):find()
+end
+
+-- find normal mode mappings
+internal.keymaps = function(opts)
+ local modes = {"n", "i", "c"}
+ local keymaps_table = {}
+ for _, mode in pairs(modes) do
+ local keymaps_iter = vim.api.nvim_get_keymap(mode)
+ for _, keymap in pairs(keymaps_iter) do
+ table.insert(keymaps_table, keymap)
+ end
+ end
+
+ pickers.new({}, {
+ prompt_title = 'Key Maps',
+ finder = finders.new_table {
+ results = keymaps_table,
+ entry_maker = function(line)
+ return {
+ valid = line ~= "",
+ value = line,
+ ordinal = line.lhs .. line.rhs,
+ display = line.mode .. ' ' .. utils.display_termcodes(line.lhs) .. ' ' .. line.rhs
+ }
+ end
+ },
+ sorter = conf.generic_sorter(opts),
+ }):find()
+end
+
+internal.filetypes = function(opts)
+ local filetypes = vim.fn.getcompletion('', 'filetype')
+
+ pickers.new({}, {
+ prompt_title = 'Filetypes',
+ finder = finders.new_table {
+ results = filetypes,
+ },
+ sorter = conf.generic_sorter(opts),
+ attach_mappings = function(prompt_bufnr)
+ actions.goto_file_selection_edit:replace(function()
+ local selection = actions.get_selected_entry()
+ actions.close(prompt_bufnr)
+ vim.cmd('setfiletype ' .. selection[1])
+ end)
+ return true
+ end
+ }):find()
+end
+
+internal.highlights = function(opts)
+ local highlights = vim.fn.getcompletion('', 'highlight')
+
+ pickers.new({}, {
+ prompt_title = 'Highlights',
+ finder = finders.new_table {
+ results = highlights,
+ entry_maker = make_entry.gen_from_highlights(opts)
+ },
+ sorter = conf.generic_sorter(opts),
+ attach_mappings = function(prompt_bufnr)
+ actions.goto_file_selection_edit:replace(function()
+ local selection = actions.get_selected_entry()
+ actions.close(prompt_bufnr)
+ vim.cmd('hi ' .. selection.value)
+ end)
+ return true
+ end,
+ previewer = previewers.display_content.new(opts),
+ }):find()
+end
+
+
+local function apply_checks(mod)
+ for k, v in pairs(mod) do
+ mod[k] = function(opts)
+ opts = opts or {}
+
+ v(opts)
+ end
+ end
+
+ return mod
+end
+
+return apply_checks(internal)
diff --git a/lua/telescope/builtin/lsp.lua b/lua/telescope/builtin/lsp.lua
new file mode 100644
index 0000000..50acdc9
--- /dev/null
+++ b/lua/telescope/builtin/lsp.lua
@@ -0,0 +1,182 @@
+local actions = require('telescope.actions')
+local finders = require('telescope.finders')
+local make_entry = require('telescope.make_entry')
+local pickers = require('telescope.pickers')
+local previewers = require('telescope.previewers')
+local utils = require('telescope.utils')
+
+local conf = require('telescope.config').values
+
+local lsp = {}
+
+lsp.references = function(opts)
+ opts.shorten_path = utils.get_default(opts.shorten_path, true)
+
+ local params = vim.lsp.util.make_position_params()
+ params.context = { includeDeclaration = true }
+
+ local results_lsp = vim.lsp.buf_request_sync(0, "textDocument/references", params, opts.timeout or 10000)
+ local locations = {}
+ for _, server_results in pairs(results_lsp) do
+ if server_results.result then
+ vim.list_extend(locations, vim.lsp.util.locations_to_items(server_results.result) or {})
+ end
+ end
+
+ if vim.tbl_isempty(locations) then
+ return
+ end
+
+ pickers.new(opts, {
+ prompt_title = 'LSP References',
+ finder = finders.new_table {
+ results = locations,
+ entry_maker = make_entry.gen_from_quickfix(opts),
+ },
+ previewer = previewers.qflist.new(opts),
+ sorter = conf.generic_sorter(opts),
+ }):find()
+end
+
+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, opts.timeout or 10000)
+
+ 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_title = 'LSP Document Symbols',
+ finder = finders.new_table {
+ results = locations,
+ entry_maker = make_entry.gen_from_quickfix(opts)
+ },
+ previewer = previewers.qflist.new(opts),
+ sorter = conf.generic_sorter(opts),
+ }):find()
+end
+
+lsp.code_actions = function(opts)
+ local params = vim.lsp.util.make_range_params()
+
+ params.context = {
+ diagnostics = vim.lsp.diagnostic.get_line_diagnostics()
+ }
+
+ local results_lsp, err = vim.lsp.buf_request_sync(0, "textDocument/codeAction", params, opts.timeout or 10000)
+
+ if err then
+ print("ERROR: " .. err)
+ return
+ end
+
+ if not results_lsp or vim.tbl_isempty(results_lsp) then
+ print("No results from textDocument/codeAction")
+ return
+ end
+
+ local results = (results_lsp[1] or results_lsp[2]).result;
+
+ if not results or #results == 0 then
+ print("No code actions available")
+ return
+ end
+
+ for i,x in ipairs(results) do
+ x.idx = i
+ end
+
+ pickers.new(opts, {
+ prompt_title = 'LSP Code Actions',
+ finder = finders.new_table {
+ results = results,
+ entry_maker = function(line)
+ return {
+ valid = line ~= nil,
+ value = line,
+ ordinal = line.idx .. line.title,
+ display = line.idx .. ': ' .. line.title
+ }
+ end
+ },
+ attach_mappings = function(prompt_bufnr)
+ actions.goto_file_selection_edit:replace(function()
+ local selection = actions.get_selected_entry()
+ actions.close(prompt_bufnr)
+ local val = selection.value
+
+ if val.edit or type(val.command) == "table" then
+ if val.edit then
+ vim.lsp.util.apply_workspace_edit(val.edit)
+ end
+ if type(val.command) == "table" then
+ vim.lsp.buf.execute_command(val.command)
+ end
+ else
+ vim.lsp.buf.execute_command(val)
+ end
+ end)
+
+ return true
+ end,
+ sorter = conf.generic_sorter(opts),
+ }):find()
+end
+
+lsp.workspace_symbols = function(opts)
+ opts.shorten_path = utils.get_default(opts.shorten_path, true)
+
+ local params = {query = opts.query or ''}
+ local results_lsp = vim.lsp.buf_request_sync(0, "workspace/symbol", params, opts.timeout or 10000)
+
+ if not results_lsp or vim.tbl_isempty(results_lsp) then
+ print("No results from workspace/symbol")
+ return
+ end
+
+ local locations = {}
+ for _, server_results in pairs(results_lsp) do
+ if server_results.result then
+ vim.list_extend(locations, vim.lsp.util.symbols_to_items(server_results.result, 0) or {})
+ end
+ end
+
+ if vim.tbl_isempty(locations) then
+ return
+ end
+
+ pickers.new(opts, {
+ prompt_title = 'LSP Workspace Symbols',
+ finder = finders.new_table {
+ results = locations,
+ entry_maker = make_entry.gen_from_quickfix(opts)
+ },
+ previewer = previewers.qflist.new(opts),
+ sorter = conf.generic_sorter(opts),
+ }):find()
+end
+
+local function apply_checks(mod)
+ for k, v in pairs(mod) do
+ mod[k] = function(opts)
+ opts = opts or {}
+
+ v(opts)
+ end
+ end
+
+ return mod
+end
+
+return apply_checks(lsp)
diff --git a/lua/telescope/make_entry.lua b/lua/telescope/make_entry.lua
index fc8b569..2a4ae5c 100644
--- a/lua/telescope/make_entry.lua
+++ b/lua/telescope/make_entry.lua
@@ -329,7 +329,7 @@ function make_entry.gen_from_buffer(opts)
bufnr = entry.bufnr,
filename = bufname,
- lnum = entry.info.lnum or 1,
+ lnum = entry.info.lnum and entry.info.lnum or 1,
indicator = indicator,
}
end
diff --git a/lua/telescope/previewers.lua b/lua/telescope/previewers.lua
index ee98f1c..a51c17e 100644
--- a/lua/telescope/previewers.lua
+++ b/lua/telescope/previewers.lua
@@ -474,6 +474,7 @@ previewers.ctags = defaulter(function(_)
vim.api.nvim_win_set_option(status.preview_win, 'scrolloff', 999)
pcall(vim.fn.matchdelete, self.state.hl_id, self.state.hl_win)
+ vim.cmd "norm! gg"
vim.fn.search(scode)
self.state.hl_win = status.preview_win
@@ -483,6 +484,45 @@ previewers.ctags = defaulter(function(_)
}
end, {})
+previewers.builtin = defaulter(function(_)
+ return previewers.new_buffer_previewer {
+ setup = function()
+ return {}
+ end,
+
+ teardown = function(self)
+ if self.state and self.state.hl_id then
+ pcall(vim.fn.matchdelete, self.state.hl_id, self.state.hl_win)
+ self.state.hl_id = nil
+ end
+ end,
+
+ preview_fn = function(self, entry, status)
+ with_preview_window(status, nil, function()
+ local module_name = vim.fn.fnamemodify(entry.filename, ':t:r')
+ local text = module_name .. '\\.' .. entry.text
+
+ local new_bufnr = vim.fn.bufnr(entry.filename, true)
+ vim.fn.bufload(new_bufnr)
+
+ vim.api.nvim_win_set_buf(status.preview_win, new_bufnr)
+ vim.api.nvim_win_set_option(status.preview_win, 'wrap', false)
+ vim.api.nvim_win_set_option(status.preview_win, 'winhl', 'Normal:Normal')
+ 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, 'scrolloff', 999)
+
+ pcall(vim.fn.matchdelete, self.state.hl_id, self.state.hl_win)
+ vim.cmd "norm! gg"
+ vim.fn.search(text)
+
+ self.state.hl_win = status.preview_win
+ self.state.hl_id = vim.fn.matchadd('Search', text)
+ end)
+ end
+ }
+end, {})
+
previewers.qflist = defaulter(function(opts)
opts = opts or {}