added initial skim (rust fzf) support

main
bhagwan 3 years ago
parent 25b53481f4
commit 976ee88400

@ -165,6 +165,7 @@ require'fzf-lua'.setup {
win_col = 0.50, -- window col position (0=left, 1=right) win_col = 0.50, -- window col position (0=left, 1=right)
-- win_border = false, -- window border? or borderchars? -- win_border = false, -- window border? or borderchars?
win_border = { '╭', '─', '╮', '│', '╯', '─', '╰', '│' }, win_border = { '╭', '─', '╮', '│', '╯', '─', '╰', '│' },
-- fzf_bin = 'sk', -- use skim instead of fzf?
fzf_layout = 'reverse', -- fzf '--layout=' fzf_layout = 'reverse', -- fzf '--layout='
fzf_args = '', -- adv: fzf extra args, empty unless adv fzf_args = '', -- adv: fzf extra args, empty unless adv
preview_cmd = '', -- 'head -n $FZF_PREVIEW_LINES', preview_cmd = '', -- 'head -n $FZF_PREVIEW_LINES',

@ -16,6 +16,7 @@ M.win_row = 0.30
M.win_col = 0.50 M.win_col = 0.50
M.win_border = true M.win_border = true
M.default_prompt = '> ' M.default_prompt = '> '
M.fzf_bin = nil
M.fzf_layout = 'reverse' M.fzf_layout = 'reverse'
M.preview_cmd = nil -- auto detect head|bat M.preview_cmd = nil -- auto detect head|bat
M.preview_border = 'border' M.preview_border = 'border'

@ -47,11 +47,12 @@ M.build_fzf_cli = function(opts)
local cfg = require'fzf-lua.config' local cfg = require'fzf-lua.config'
opts.prompt = opts.prompt or cfg.default_prompt opts.prompt = opts.prompt or cfg.default_prompt
opts.preview_offset = opts.preview_offset or '' opts.preview_offset = opts.preview_offset or ''
opts.fzf_bin = opts.fzf_bin or cfg.fzf_bin
local cli = string.format( local cli = string.format(
[[ %s --layout=%s --bind=%s --prompt=%s]] .. [[ %s --layout=%s --bind=%s --prompt=%s]] ..
[[ --preview-window='%s%s' --preview=%s]] .. [[ --preview-window='%s%s' --preview=%s]] ..
[[ --height=100%% --ansi --info=inline]] .. [[ --height=100%% --ansi]] ..
[[ %s %s %s]], [[ %s %s %s %s]],
opts.fzf_args or cfg.fzf_args or '', opts.fzf_args or cfg.fzf_args or '',
opts.fzf_layout or cfg.fzf_layout, opts.fzf_layout or cfg.fzf_layout,
utils._if(opts.fzf_binds, opts.fzf_binds, utils._if(opts.fzf_binds, opts.fzf_binds,
@ -60,6 +61,8 @@ M.build_fzf_cli = function(opts)
utils._if(opts.preview_window, opts.preview_window, cfg.preview_window()), utils._if(opts.preview_window, opts.preview_window, cfg.preview_window()),
utils._if(#opts.preview_offset>0, ":"..opts.preview_offset, ''), utils._if(#opts.preview_offset>0, ":"..opts.preview_offset, ''),
utils._if(opts.preview, opts.preview, M.preview_cmd(opts, cfg)), utils._if(opts.preview, opts.preview, M.preview_cmd(opts, cfg)),
-- HACK: support skim (rust version of fzf)
utils._if(opts.fzf_bin and opts.fzf_bin:find('sk')~=nil, "--inline-info", "--info=inline"),
utils._if(actions.expect(opts.actions), actions.expect(opts.actions), ''), utils._if(actions.expect(opts.actions), actions.expect(opts.actions), ''),
utils._if(opts.nomulti, '--no-multi', '--multi'), utils._if(opts.nomulti, '--no-multi', '--multi'),
utils._if(opts.cli_args, opts.cli_args, '') utils._if(opts.cli_args, opts.cli_args, '')
@ -154,11 +157,6 @@ end
M.fzf_files = function(opts) M.fzf_files = function(opts)
if not opts or not opts.fzf_fn then
utils.warn("Core.fzf_files(opts) cannot run without callback fn")
return
end
-- reset git tracking -- reset git tracking
opts.diff_files, opts.untracked_files = nil, nil opts.diff_files, opts.untracked_files = nil, nil
if not utils.is_git_repo() then opts.git_icons = false end if not utils.is_git_repo() then opts.git_icons = false end

@ -53,6 +53,7 @@ function M.setup(opts)
win_border = "any", -- boolean|table (borderchars) win_border = "any", -- boolean|table (borderchars)
winopts_raw = "function", winopts_raw = "function",
default_prompt = "string", default_prompt = "string",
fzf_bin = "string",
fzf_args = "string", fzf_args = "string",
fzf_layout = "string", fzf_layout = "string",
fzf_binds = "table", fzf_binds = "table",
@ -185,6 +186,8 @@ function M.setup(opts)
end end
-- reset default window opts if set by user -- reset default window opts if set by user
fzf.default_window_options = config.winopts() fzf.default_window_options = config.winopts()
-- set the fzf binary if set by the user
if config.fzf_bin then fzf.fzf_binary = config.fzf_bin end
end end
-- we usually send winopts with every fzf.fzf call -- we usually send winopts with every fzf.fzf call

@ -11,7 +11,7 @@ local config = require "fzf-lua.config"
local M = {} local M = {}
local get_grep_cmd = function(opts) local get_grep_cmd = function(opts, search_query, no_esc)
local command = nil local command = nil
if opts.cmd and #opts.cmd > 0 then if opts.cmd and #opts.cmd > 0 then
@ -30,11 +30,12 @@ local get_grep_cmd = function(opts)
search_path = vim.fn.shellescape(opts.cwd) search_path = vim.fn.shellescape(opts.cwd)
end end
return string.format("%s -- %s %s", command, if search_query == nil then search_query = ''
utils._if(opts.last_search and #opts.last_search>0, elseif not no_esc then
vim.fn.shellescape(opts.last_search), "{q}"), search_query = vim.fn.shellescape(utils.rg_escape(search_query))
search_path end
)
return string.format("%s -- %s %s", command, search_query, search_path)
end end
M.grep = function(opts) M.grep = function(opts)
@ -46,28 +47,26 @@ M.grep = function(opts)
"rg_opts", "grep_opts", "rg_opts", "grep_opts",
}) })
if opts.search and #opts.search>0 then if opts.continue_last_search or opts.repeat_last_search then
opts.search = utils.rg_escape(opts.search)
end
if opts.repeat_last_search == true then
opts.search = config.grep.last_search opts.search = config.grep.last_search
end end
-- save the next search as last_search so we
-- let the caller have an option to run the -- if user did not provide a search term
-- same search again -- provide an input prompt
if not opts.search or #opts.search == 0 then if not opts.search or #opts.search == 0 then
config.grep.last_search = vim.fn.input(opts.input_prompt) opts.search = vim.fn.input(opts.input_prompt)
else
config.grep.last_search = opts.search
end end
opts.last_search = config.grep.last_search
if not opts.last_search or #opts.last_search == 0 then if not opts.search or #opts.search == 0 then
utils.info("Please provider valid search string") utils.info("Please provide a valid search string")
return return
end end
local command = get_grep_cmd(opts) -- 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( opts.fzf_fn = fzf_helpers.cmd_line_transformer(
command, command,
@ -94,9 +93,35 @@ M.grep = function(opts)
]] ]]
opts.preview_offset = "+{3}-/2" opts.preview_offset = "+{3}-/2"
core.fzf_files(opts) core.fzf_files(opts)
opts.search = nil
end 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) M.live_grep = function(opts)
opts = config.getopts(opts, config.grep, { opts = config.getopts(opts, config.grep, {
@ -106,41 +131,33 @@ M.live_grep = function(opts)
"rg_opts", "grep_opts", "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 if opts.search and #opts.search>0 then
opts.search = utils.rg_escape(opts.search) -- save the search query so the use can
-- call the same search again
config.grep.last_search = opts.search
end end
-- resetting last_search will return -- HACK: support skim (rust version of fzf)
-- {q} placeholder in our command opts.fzf_bin = opts.fzf_bin or config.fzf_bin
opts.last_search = opts.search if opts.fzf_bin and opts.fzf_bin:find('sk')~=nil then
local initial_command = get_grep_cmd(opts) return M.live_grep_sk(opts)
opts.last_search = nil end
local reload_command = get_grep_cmd(opts) .. " || true"
--[[ local fzf_binds = utils.tbl_deep_clone(config.fzf_binds) -- use {q} as a placeholder for fzf
table.insert(fzf_binds, string.format("change:reload:%s", reload_command)) local initial_command = get_grep_cmd(opts, opts.search)
opts.fzf_binds = vim.fn.shellescape(table.concat(fzf_binds, ',')) ]] local reload_command = get_grep_cmd(opts, "{q}", true) .. " || true"
opts.cli_args = "--delimiter='[: ]' " .. opts.cli_args = "--delimiter='[: ]' " ..
string.format("--phony --query=%s --bind=%s", string.format("--phony --query=%s --bind=%s",
utils._if(opts.search and #opts.search>0, opts.search, [['']]), 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))) vim.fn.shellescape(string.format("change:reload:%s", reload_command)))
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"
-- TODO: -- TODO:
-- this is not getting called past the initial command -- this is not getting called past the initial command
-- until we fix that we cannot use icons as they interfere -- until we fix that we cannot use icons as they interfere
@ -158,11 +175,12 @@ M.live_grep = function(opts)
end) end)
core.fzf_files(opts) core.fzf_files(opts)
opts.search = nil
end end
M.grep_last = function(opts) M.grep_last = function(opts)
if not opts then opts = {} end if not opts then opts = {} end
opts.repeat_last_search = true opts.continue_last_search = true
return M.grep(opts) return M.grep(opts)
end end

@ -88,7 +88,7 @@ local fzf_function = function (cb)
end end
end end
-- done -- done
-- cb(nil) cb(nil, function() end)
end)() end)()
end end

@ -122,7 +122,11 @@ local function set_lsp_fzf_fn(opts)
-- we use this passthrough so we can send the -- we use this passthrough so we can send the
-- coroutine variable (not used rn but who knows?) -- coroutine variable (not used rn but who knows?)
opts.lsp_handler.target = function(_, _, result) opts.lsp_handler.target = function(_, _, result)
return opts.lsp_handler.handler(opts, cb, co, result) opts.lsp_handler.handler(opts, cb, co, result)
-- close the pipe to fzf, this
-- removes the loading indicator in fzf
cb(nil, function() end)
return
end end
local _, cancel_all = vim.lsp.buf_request(opts.bufnr, local _, cancel_all = vim.lsp.buf_request(opts.bufnr,
@ -375,6 +379,9 @@ M.diagnostics = function(opts)
end end
end end
-- coroutine.yield() -- coroutine.yield()
-- close the pipe to fzf, this
-- removes the loading indicator in fzf
cb(nil, function() end)
end)() end)()
end end

@ -54,10 +54,12 @@ M.oldfiles = function(opts)
x = core.make_entry_file(opts, x) x = core.make_entry_file(opts, x)
cb(x, function(err) cb(x, function(err)
if err then return end if err then return end
-- cb(nil) -- to close the pipe to fzf, this removes the loading -- close the pipe to fzf, this
-- indicator in fzf -- removes the loading indicator in fzf
cb(nil, function() end)
end) end)
end end
cb(nil, function() end)
end end
--[[ opts.cb_selected = function(_, x) --[[ opts.cb_selected = function(_, x)

@ -31,10 +31,12 @@ local quickfix_run = function(opts, cfg, locations)
x = core.make_entry_file(opts, x) x = core.make_entry_file(opts, x)
cb(x, function(err) cb(x, function(err)
if err then return end if err then return end
-- cb(nil) -- to close the pipe to fzf, this removes the loading -- close the pipe to fzf, this
-- indicator in fzf -- removes the loading indicator in fzf
cb(nil, function() end)
end) end)
end end
cb(nil, function() end)
end end
--[[ opts.cb_selected = function(_, x) --[[ opts.cb_selected = function(_, x)

@ -55,9 +55,10 @@ function M.is_git_repo()
end end
function M.rg_escape(str) function M.rg_escape(str)
if not str then return str end
-- [(~'"\/$?'`*&&||;[]<>)] -- [(~'"\/$?'`*&&||;[]<>)]
-- escape "\~$?*|[()" -- escape "\~$?*|[()"
return str:gsub("[\\~$?*|\\[()]", function(x) return str:gsub("[\\~$?*|{\\[()]", function(x)
return '\\' .. x return '\\' .. x
end) end)
end end

Loading…
Cancel
Save