summaryrefslogtreecommitdiff
path: root/lua/telescope/builtin/files.lua
diff options
context:
space:
mode:
Diffstat (limited to 'lua/telescope/builtin/files.lua')
-rw-r--r--lua/telescope/builtin/files.lua533
1 files changed, 14 insertions, 519 deletions
diff --git a/lua/telescope/builtin/files.lua b/lua/telescope/builtin/files.lua
index dddd18a..645fc10 100644
--- a/lua/telescope/builtin/files.lua
+++ b/lua/telescope/builtin/files.lua
@@ -1,522 +1,17 @@
-local action_state = require "telescope.actions.state"
-local action_set = require "telescope.actions.set"
-local finders = require "telescope.finders"
-local make_entry = require "telescope.make_entry"
-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 log = require "telescope.log"
-
-local Path = require "plenary.path"
-
-local flatten = vim.tbl_flatten
-local filter = vim.tbl_filter
-
-local files = {}
-
-local escape_chars = function(string)
- return string.gsub(string, "[%(|%)|\\|%[|%]|%-|%{%}|%?|%+|%*|%^|%$|%.]", {
- ["\\"] = "\\\\",
- ["-"] = "\\-",
- ["("] = "\\(",
- [")"] = "\\)",
- ["["] = "\\[",
- ["]"] = "\\]",
- ["{"] = "\\{",
- ["}"] = "\\}",
- ["?"] = "\\?",
- ["+"] = "\\+",
- ["*"] = "\\*",
- ["^"] = "\\^",
- ["$"] = "\\$",
- ["."] = "\\.",
- })
-end
-
--- Special keys:
--- opts.search_dirs -- list of directory to search in
--- opts.grep_open_files -- boolean to restrict search to open files
-files.live_grep = function(opts)
- local vimgrep_arguments = opts.vimgrep_arguments or conf.vimgrep_arguments
- local search_dirs = opts.search_dirs
- local grep_open_files = opts.grep_open_files
- opts.cwd = opts.cwd and vim.fn.expand(opts.cwd) or vim.loop.cwd()
-
- local filelist = {}
-
- if grep_open_files then
- local bufnrs = filter(function(b)
- if 1 ~= vim.fn.buflisted(b) then
- return false
- end
- return true
- end, vim.api.nvim_list_bufs())
- if not next(bufnrs) then
- return
- end
-
- for _, bufnr in ipairs(bufnrs) do
- local file = vim.api.nvim_buf_get_name(bufnr)
- table.insert(filelist, Path:new(file):make_relative(opts.cwd))
- end
- elseif search_dirs then
- for i, path in ipairs(search_dirs) do
- search_dirs[i] = vim.fn.expand(path)
- end
- end
-
- local additional_args = {}
- if opts.additional_args ~= nil and type(opts.additional_args) == "function" then
- additional_args = opts.additional_args(opts)
- end
-
- if opts.type_filter then
- additional_args[#additional_args + 1] = "--type=" .. opts.type_filter
- end
-
- if type(opts.glob_pattern) == "string" then
- additional_args[#additional_args + 1] = "--glob=" .. opts.glob_pattern
- elseif type(opts.glob_pattern) == "table" then
- for i = 1, #opts.glob_pattern do
- additional_args[#additional_args + 1] = "--glob=" .. opts.glob_pattern[i]
- end
- end
-
- 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
-
- local search_list = {}
-
- if search_dirs then
- table.insert(search_list, search_dirs)
- end
-
- if grep_open_files then
- search_list = filelist
- end
-
- return flatten { vimgrep_arguments, additional_args, "--", prompt, search_list }
- end, opts.entry_maker or make_entry.gen_from_vimgrep(opts), opts.max_results, opts.cwd)
-
- pickers.new(opts, {
- prompt_title = "Live Grep",
- finder = live_grepper,
- previewer = conf.grep_previewer(opts),
- -- TODO: It would be cool to use `--json` output for this
- -- and then we could get the highlight positions directly.
- sorter = sorters.highlighter_only(opts),
- attach_mappings = function(_, map)
- map("i", "<c-space>", function(prompt_bufnr)
- local line = action_state.get_current_line()
- require("telescope.actions.generate").refine(prompt_bufnr, {
- prompt_title = "Find Word (" .. line .. ")",
- sorter = conf.generic_sorter(opts),
- })
- end)
- return true
- end,
- }):find()
-end
-
--- Special keys:
--- opts.search -- the string to search.
--- opts.search_dirs -- list of directory to search in
--- opts.use_regex -- special characters won't be escaped
-files.grep_string = function(opts)
- -- TODO: This should probably check your visual selection as well, if you've got one
-
- local vimgrep_arguments = opts.vimgrep_arguments or conf.vimgrep_arguments
- local search_dirs = opts.search_dirs
- local word = opts.search or vim.fn.expand "<cword>"
- local search = opts.use_regex and word or escape_chars(word)
- local word_match = opts.word_match
- opts.entry_maker = opts.entry_maker or make_entry.gen_from_vimgrep(opts)
-
- local title_word = word:gsub("\n", "\\n")
-
- local additional_args = {}
- if opts.additional_args ~= nil and type(opts.additional_args) == "function" then
- additional_args = opts.additional_args(opts)
- end
-
- local args = flatten {
- vimgrep_arguments,
- additional_args,
- word_match,
- "--",
- search,
- }
-
- if search_dirs then
- for _, path in ipairs(search_dirs) do
- table.insert(args, vim.fn.expand(path))
- end
- end
-
- pickers.new(opts, {
- prompt_title = "Find Word (" .. title_word .. ")",
- finder = finders.new_oneshot_job(args, opts),
- previewer = conf.grep_previewer(opts),
- sorter = conf.generic_sorter(opts),
- }):find()
-end
-
-files.find_files = function(opts)
- local find_command = (function()
- if opts.find_command then
- if type(opts.find_command) == "function" then
- return opts.find_command(opts)
- end
- return opts.find_command
- elseif 1 == vim.fn.executable "fd" then
- return { "fd", "--type", "f" }
- elseif 1 == vim.fn.executable "fdfind" then
- return { "fdfind", "--type", "f" }
- elseif 1 == vim.fn.executable "rg" then
- return { "rg", "--files" }
- elseif 1 == vim.fn.executable "find" and vim.fn.has "win32" == 0 then
- return { "find", ".", "-type", "f" }
- elseif 1 == vim.fn.executable "where" then
- return { "where", "/r", ".", "*" }
- end
- end)()
-
- if not find_command then
- utils.notify("builtin.find_files", {
- msg = "You need to install either find, fd, or rg",
- level = "ERROR",
- })
- return
- end
-
- local command = find_command[1]
- local hidden = opts.hidden
- local no_ignore = opts.no_ignore
- local no_ignore_parent = opts.no_ignore_parent
- local follow = opts.follow
- local search_dirs = opts.search_dirs
- local search_file = opts.search_file
-
- if search_dirs then
- for k, v in pairs(search_dirs) do
- search_dirs[k] = vim.fn.expand(v)
- end
- end
-
- if command == "fd" or command == "fdfind" or command == "rg" then
- if hidden then
- table.insert(find_command, "--hidden")
- end
- if no_ignore then
- table.insert(find_command, "--no-ignore")
- end
- if no_ignore_parent then
- table.insert(find_command, "--no-ignore-parent")
- end
- if follow then
- table.insert(find_command, "-L")
- end
- if search_file then
- if command == "rg" then
- table.insert(find_command, "-g")
- table.insert(find_command, "*" .. search_file .. "*")
- else
- table.insert(find_command, search_file)
- end
- end
- if search_dirs then
- if command ~= "rg" and not search_file then
- table.insert(find_command, ".")
- end
- for _, v in pairs(search_dirs) do
- table.insert(find_command, v)
- end
- end
- elseif command == "find" then
- if not hidden then
- table.insert(find_command, { "-not", "-path", "*/.*" })
- find_command = flatten(find_command)
- end
- if no_ignore ~= nil then
- log.warn "The `no_ignore` key is not available for the `find` command in `find_files`."
- end
- if no_ignore_parent ~= nil then
- log.warn "The `no_ignore_parent` key is not available for the `find` command in `find_files`."
- end
- if follow then
- table.insert(find_command, 2, "-L")
- end
- if search_file then
- table.insert(find_command, "-name")
- table.insert(find_command, "*" .. search_file .. "*")
- end
- if search_dirs then
- table.remove(find_command, 2)
- for _, v in pairs(search_dirs) do
- table.insert(find_command, 2, v)
- end
- end
- elseif command == "where" then
- if hidden ~= nil then
- log.warn "The `hidden` key is not available for the Windows `where` command in `find_files`."
- end
- if no_ignore ~= nil then
- log.warn "The `no_ignore` key is not available for the Windows `where` command in `find_files`."
- end
- if no_ignore_parent ~= nil then
- log.warn "The `no_ignore_parent` key is not available for the Windows `where` command in `find_files`."
- end
- if follow ~= nil then
- log.warn "The `follow` key is not available for the Windows `where` command in `find_files`."
- end
- if search_dirs ~= nil then
- log.warn "The `search_dirs` key is not available for the Windows `where` command in `find_files`."
- end
- if search_file ~= nil then
- log.warn "The `search_file` key is not available for the Windows `where` command in `find_files`."
- end
- 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 = conf.file_previewer(opts),
- sorter = conf.file_sorter(opts),
- }):find()
-end
-
-local function prepare_match(entry, kind)
- local entries = {}
-
- if entry.node then
- 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
-
--- TODO: finish docs for opts.show_line
-files.treesitter = function(opts)
- opts.show_line = vim.F.if_nil(opts.show_line, true)
-
- local has_nvim_treesitter, _ = pcall(require, "nvim-treesitter")
- if not has_nvim_treesitter then
- utils.notify("builtin.treesitter", {
- msg = "User need to install nvim-treesitter needs to be installed",
- level = "ERROR",
- })
- return
- end
-
- local parsers = require "nvim-treesitter.parsers"
- if not parsers.has_parser(parsers.get_buf_lang(opts.bufnr)) then
- utils.notify("builtin.treesitter", {
- msg = "No parser for the current buffer",
- level = "ERROR",
- })
- return
- end
-
- local ts_locals = require "nvim-treesitter.locals"
- local results = {}
- for _, definition in ipairs(ts_locals.get_definitions(opts.bufnr)) do
- local entries = prepare_match(ts_locals.get_local_nodes(definition))
- for _, entry in ipairs(entries) do
- entry.kind = vim.F.if_nil(entry.kind, "")
- 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 = opts.entry_maker or make_entry.gen_from_treesitter(opts),
- },
- previewer = conf.grep_previewer(opts),
- sorter = conf.prefilter_sorter {
- tag = "kind",
- sorter = conf.generic_sorter(opts),
- },
- }):find()
-end
-
-files.current_buffer_fuzzy_find = function(opts)
- -- All actions are on the current buffer
- local filename = vim.fn.expand(vim.api.nvim_buf_get_name(opts.bufnr))
- local filetype = vim.api.nvim_buf_get_option(opts.bufnr, "filetype")
-
- local lines = vim.api.nvim_buf_get_lines(opts.bufnr, 0, -1, false)
- local lines_with_numbers = {}
-
- for lnum, line in ipairs(lines) do
- table.insert(lines_with_numbers, {
- lnum = lnum,
- bufnr = opts.bufnr,
- filename = filename,
- text = line,
- })
- end
-
- local ts_ok, ts_parsers = pcall(require, "nvim-treesitter.parsers")
- if ts_ok then
- filetype = ts_parsers.ft_to_lang(filetype)
- end
- local _, ts_configs = pcall(require, "nvim-treesitter.configs")
-
- local parser_ok, parser = pcall(vim.treesitter.get_parser, opts.bufnr, filetype)
- local query_ok, query = pcall(vim.treesitter.get_query, filetype, "highlights")
- if parser_ok and query_ok and ts_ok and ts_configs.is_enabled("highlight", filetype, opts.bufnr) then
- local root = parser:parse()[1]:root()
-
- local highlighter = vim.treesitter.highlighter.new(parser)
- local highlighter_query = highlighter:get_query(filetype)
-
- local line_highlights = setmetatable({}, {
- __index = function(t, k)
- local obj = {}
- rawset(t, k, obj)
- return obj
- end,
- })
- for id, node in query:iter_captures(root, opts.bufnr, 0, -1) do
- local hl = highlighter_query:_get_hl_from_capture(id)
- if hl and type(hl) ~= "number" then
- local row1, col1, row2, col2 = node:range()
-
- if row1 == row2 then
- local row = row1 + 1
-
- for index = col1, col2 do
- line_highlights[row][index] = hl
- end
- else
- local row = row1 + 1
- for index = col1, #lines[row] do
- line_highlights[row][index] = hl
- end
-
- while row < row2 + 1 do
- row = row + 1
-
- for index = 0, #(lines[row] or {}) do
- line_highlights[row][index] = hl
- end
- end
- end
- end
- end
-
- opts.line_highlights = line_highlights
- end
-
- pickers.new(opts, {
- prompt_title = "Current Buffer Fuzzy",
- finder = finders.new_table {
- results = lines_with_numbers,
- entry_maker = opts.entry_maker or make_entry.gen_from_buffer_lines(opts),
- },
- sorter = conf.generic_sorter(opts),
- previewer = conf.grep_previewer(opts),
- attach_mappings = function()
- action_set.select:enhance {
- post = function()
- local selection = action_state.get_selected_entry()
- vim.api.nvim_win_set_cursor(0, { selection.lnum, 0 })
- end,
- }
-
- return true
- end,
- }):find()
-end
-
-files.tags = function(opts)
- local tagfiles = opts.ctags_file and { opts.ctags_file } or vim.fn.tagfiles()
- for i, ctags_file in ipairs(tagfiles) do
- tagfiles[i] = vim.fn.expand(ctags_file, true)
- end
- if vim.tbl_isempty(tagfiles) then
- utils.notify("builtin.tags", {
- msg = "No tags file found. Create one with ctags -R",
+local m = setmetatable({}, {
+ __index = function(_, k)
+ local utils = require "telescope.utils"
+ utils.notify("builtin", {
+ msg = string.format(
+ 'You are using an internal interface. Do not use `require("telescope.builtin.files").%s`,'
+ .. ' please use `require("telescope.builtin").%s`! We will remove this endpoint soon!',
+ k,
+ k
+ ),
level = "ERROR",
})
- return
- end
- opts.entry_maker = vim.F.if_nil(opts.entry_maker, make_entry.gen_from_ctags(opts))
-
- pickers.new(opts, {
- prompt_title = "Tags",
- finder = finders.new_oneshot_job(flatten { "cat", tagfiles }, opts),
- previewer = previewers.ctags.new(opts),
- sorter = conf.generic_sorter(opts),
- attach_mappings = function()
- action_set.select:enhance {
- post = function()
- local selection = action_state.get_selected_entry()
- if not selection then
- return
- end
-
- if selection.scode then
- -- un-escape / then escape required
- -- special chars for vim.fn.search()
- -- ] ~ *
- local scode = selection.scode:gsub([[\/]], "/"):gsub("[%]~*]", function(x)
- return "\\" .. x
- end)
-
- vim.cmd "norm! gg"
- vim.fn.search(scode)
- vim.cmd "norm! zz"
- else
- vim.api.nvim_win_set_cursor(0, { selection.lnum, 0 })
- end
- end,
- }
- return true
- end,
- }):find()
-end
-
-files.current_buffer_tags = function(opts)
- return files.tags(vim.tbl_extend("force", {
- prompt_title = "Current Buffer Tags",
- only_current_file = true,
- path_display = "hidden",
- }, 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 require("telescope.builtin")[k]
+ end,
+})
-return apply_checks(files)
+return m