You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
219 lines
5.8 KiB
Lua
219 lines
5.8 KiB
Lua
if not pcall(require, "fzf") then
|
|
return
|
|
end
|
|
|
|
-- local fzf = require "fzf"
|
|
local fzf_helpers = require("fzf.helpers")
|
|
local path = require "fzf-lua.path"
|
|
local core = require "fzf-lua.core"
|
|
local utils = require "fzf-lua.utils"
|
|
local config = require "fzf-lua.config"
|
|
|
|
local M = {}
|
|
|
|
local get_grep_cmd = function(opts, search_query, no_esc)
|
|
|
|
local command = nil
|
|
if opts.cmd and #opts.cmd > 0 then
|
|
command = opts.cmd
|
|
elseif vim.fn.executable("rg") == 1 then
|
|
command = string.format("rg %s", opts.rg_opts)
|
|
else
|
|
command = string.format("grep %s", opts.grep_opts)
|
|
end
|
|
|
|
-- filename takes precedence over directory
|
|
local search_path = ''
|
|
if opts.filename and #opts.filename>0 then
|
|
search_path = vim.fn.shellescape(opts.filename)
|
|
elseif opts.cwd and #opts.cwd>0 then
|
|
search_path = vim.fn.shellescape(opts.cwd)
|
|
end
|
|
|
|
if search_query == nil then search_query = ''
|
|
elseif not no_esc then
|
|
search_query = vim.fn.shellescape(utils.rg_escape(search_query))
|
|
end
|
|
|
|
return string.format("%s -- %s %s", command, search_query, search_path)
|
|
end
|
|
|
|
M.grep = function(opts)
|
|
|
|
opts = config.getopts(opts, config.grep, {
|
|
"cmd", "prompt", "actions", "winopts",
|
|
"file_icons", "color_icons", "git_icons",
|
|
"search", "input_prompt",
|
|
"rg_opts", "grep_opts",
|
|
})
|
|
|
|
if opts.continue_last_search or opts.repeat_last_search then
|
|
opts.search = config.grep.last_search
|
|
end
|
|
|
|
-- if user did not provide a search term
|
|
-- provide an input prompt
|
|
if not opts.search or #opts.search == 0 then
|
|
opts.search = vim.fn.input(opts.input_prompt)
|
|
end
|
|
|
|
if not opts.search or #opts.search == 0 then
|
|
utils.info("Please provide a valid search string")
|
|
return
|
|
end
|
|
|
|
-- save the search query so the use can
|
|
-- call the same search again
|
|
config.grep.last_search = opts.search
|
|
|
|
local command = get_grep_cmd(opts, opts.search)
|
|
|
|
opts.fzf_fn = fzf_helpers.cmd_line_transformer(
|
|
command,
|
|
function(x)
|
|
return core.make_entry_file(opts, x)
|
|
end)
|
|
|
|
--[[ opts.cb_selected = function(_, x)
|
|
return x
|
|
end ]]
|
|
|
|
opts.cli_args = "--delimiter='[: ]'"
|
|
opts.preview_args = "--highlight-line={3}" -- bat higlight
|
|
--[[
|
|
# Preview with bat, matching line in the middle of the window below
|
|
# the fixed header of the top 3 lines
|
|
#
|
|
# ~3 Top 3 lines as the fixed header
|
|
# +{2} Base scroll offset extracted from the second field
|
|
# +3 Extra offset to compensate for the 3-line header
|
|
# /2 Put in the middle of the preview area
|
|
#
|
|
'--preview-window '~3:+{2}+3/2''
|
|
]]
|
|
opts.preview_offset = "+{3}-/2"
|
|
core.fzf_files(opts)
|
|
opts.search = nil
|
|
end
|
|
|
|
|
|
M.live_grep_sk = function(opts)
|
|
|
|
-- "'{}'" opens sk with an empty search_query showing all files
|
|
-- "{}" opens sk without executing an empty string query
|
|
-- the problem is the latter doesn't support escaped chars
|
|
-- TODO: how to open without a query with special char support
|
|
local sk_args = get_grep_cmd(opts , "'{}'", true)
|
|
|
|
opts.cli_args = "--delimiter='[: ]' " ..
|
|
string.format("--cmd-prompt='%s' -i -c %s",
|
|
opts.prompt,
|
|
vim.fn.shellescape(sk_args))
|
|
|
|
opts.git_icons = false
|
|
opts.file_icons = false
|
|
opts.filespec = '{1}'
|
|
opts.preview_offset = "+{2}-/2"
|
|
opts.preview_args = "--highlight-line={2}"
|
|
|
|
opts.fzf_fn = nil --function(_) end
|
|
core.fzf_files(opts)
|
|
|
|
opts.search = nil
|
|
end
|
|
|
|
M.live_grep = function(opts)
|
|
|
|
opts = config.getopts(opts, config.grep, {
|
|
"cmd", "prompt", "actions", "winopts",
|
|
"file_icons", "color_icons", "git_icons",
|
|
"search", "input_prompt",
|
|
"rg_opts", "grep_opts",
|
|
})
|
|
|
|
if opts.continue_last_search or opts.repeat_last_search then
|
|
opts.search = config.grep.last_search
|
|
end
|
|
|
|
if opts.search and #opts.search>0 then
|
|
-- save the search query so the use can
|
|
-- call the same search again
|
|
config.grep.last_search = opts.search
|
|
end
|
|
|
|
-- HACK: support skim (rust version of fzf)
|
|
opts.fzf_bin = opts.fzf_bin or config.fzf_bin
|
|
if opts.fzf_bin and opts.fzf_bin:find('sk')~=nil then
|
|
return M.live_grep_sk(opts)
|
|
end
|
|
|
|
-- use {q} as a placeholder for fzf
|
|
local initial_command = get_grep_cmd(opts, opts.search)
|
|
local reload_command = get_grep_cmd(opts, "{q}", true) .. " || true"
|
|
|
|
opts.cli_args = "--delimiter='[: ]' " ..
|
|
string.format("--phony --query=%s --bind=%s",
|
|
utils._if(opts.search and #opts.search>0,
|
|
vim.fn.shellescape(utils.rg_escape(opts.search)),
|
|
[['']]),
|
|
vim.fn.shellescape(string.format("change:reload:%s", reload_command)))
|
|
|
|
-- TODO:
|
|
-- this is not getting called past the initial command
|
|
-- until we fix that we cannot use icons as they interfere
|
|
-- with the extension parsing
|
|
opts.git_icons = false
|
|
opts.file_icons = false
|
|
opts.filespec = '{1}'
|
|
opts.preview_offset = "+{2}-/2"
|
|
opts.preview_args = "--highlight-line={2}" -- bat higlight
|
|
|
|
opts.fzf_fn = fzf_helpers.cmd_line_transformer(
|
|
initial_command,
|
|
function(x)
|
|
return core.make_entry_file(opts, x)
|
|
end)
|
|
|
|
core.fzf_files(opts)
|
|
opts.search = nil
|
|
end
|
|
|
|
M.grep_last = function(opts)
|
|
if not opts then opts = {} end
|
|
opts.continue_last_search = true
|
|
return M.grep(opts)
|
|
end
|
|
|
|
M.grep_cword = function(opts)
|
|
if not opts then opts = {} end
|
|
opts.search = vim.fn.expand("<cword>")
|
|
return M.grep(opts)
|
|
end
|
|
|
|
M.grep_cWORD = function(opts)
|
|
if not opts then opts = {} end
|
|
opts.search = vim.fn.expand("<cWORD>")
|
|
return M.grep(opts)
|
|
end
|
|
|
|
M.grep_visual = function(opts)
|
|
if not opts then opts = {} end
|
|
opts.search = utils.get_visual_selection()
|
|
return M.grep(opts)
|
|
end
|
|
|
|
M.grep_curbuf = function(opts)
|
|
if not opts then opts = {} end
|
|
opts.rg_opts = config.grep.rg_opts .. " --with-filename"
|
|
opts.filename = vim.api.nvim_buf_get_name(0)
|
|
if #opts.filename > 0 then
|
|
opts.filename = path.relative(opts.filename, vim.loop.cwd())
|
|
return M.live_grep(opts)
|
|
else
|
|
utils.info("Rg current buffer requires actual file on disk")
|
|
return
|
|
end
|
|
end
|
|
|
|
return M
|