Initial commit
commit
36d850b29b
@ -0,0 +1,144 @@
|
||||
local M = {}
|
||||
|
||||
-- return fzf '--expect=' string from actions keyval tbl
|
||||
M.expect = function(actions)
|
||||
if not actions then return '' end
|
||||
local keys = {}
|
||||
for k, v in pairs(actions) do
|
||||
if k ~= "default" and v ~= false then
|
||||
table.insert(keys, k)
|
||||
end
|
||||
end
|
||||
if #keys > 0 then
|
||||
return table.concat(keys, ',')
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
M.act = function(actions, action, selected)
|
||||
if not actions or not action then return end
|
||||
if #action == 0 then action = "default" end
|
||||
if actions[action] then
|
||||
actions[action](selected)
|
||||
end
|
||||
end
|
||||
|
||||
M.vimcmd = function(vimcmd, selected)
|
||||
if not selected or #selected < 2 then return end
|
||||
for i = 2, #selected do
|
||||
vim.cmd(vimcmd .. " " .. vim.fn.fnameescape(selected[i]))
|
||||
end
|
||||
end
|
||||
|
||||
M.vimcmd_file = function(vimcmd, selected)
|
||||
if not selected or #selected < 2 then return end
|
||||
for i = 2, #selected do
|
||||
-- check if the file contains line
|
||||
local file, line = selected[i]:match("^([^ :]+):(%d+)")
|
||||
if file and line then
|
||||
vim.cmd(string.format("%s +%s %s", vimcmd, line, vim.fn.fnameescape(file)))
|
||||
else
|
||||
vim.cmd(vimcmd .. " " .. vim.fn.fnameescape(selected[i]))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- file actions
|
||||
M.file_edit = function(selected)
|
||||
local vimcmd = "e"
|
||||
M.vimcmd_file(vimcmd, selected)
|
||||
end
|
||||
|
||||
M.file_split = function(selected)
|
||||
local vimcmd = "new"
|
||||
M.vimcmd_file(vimcmd, selected)
|
||||
end
|
||||
|
||||
M.file_vsplit = function(selected)
|
||||
local vimcmd = "vnew"
|
||||
M.vimcmd_file(vimcmd, selected)
|
||||
end
|
||||
|
||||
M.file_tabedit = function(selected)
|
||||
local vimcmd = "tanbew"
|
||||
M.vimcmd_file(vimcmd, selected)
|
||||
end
|
||||
|
||||
M.file_sel_to_qf = function(selected)
|
||||
if not selected or #selected < 2 then return end
|
||||
local qf_list = {}
|
||||
for i = 2, #selected do
|
||||
-- check if the file contains line
|
||||
local file, line, col, text = selected[i]:match("^([^ :]+):(%d+):(%d+):(.*)")
|
||||
if file and line and col then
|
||||
table.insert(qf_list, {filename = file, lnum = line, col = col, text = text})
|
||||
else
|
||||
table.insert(qf_list, {filename = selected[i], lnum = 1, col = 1})
|
||||
end
|
||||
end
|
||||
vim.fn.setqflist(qf_list)
|
||||
vim.cmd 'copen'
|
||||
end
|
||||
|
||||
-- buffer actions
|
||||
M.buf_edit = function(selected)
|
||||
local vimcmd = "b"
|
||||
M.vimcmd(vimcmd, selected)
|
||||
end
|
||||
|
||||
M.buf_split = function(selected)
|
||||
local vimcmd = "split | b"
|
||||
M.vimcmd(vimcmd, selected)
|
||||
end
|
||||
|
||||
M.buf_vsplit = function(selected)
|
||||
local vimcmd = "vertical split | b"
|
||||
M.vimcmd(vimcmd, selected)
|
||||
end
|
||||
|
||||
M.buf_tabedit = function(selected)
|
||||
local vimcmd = "tab split | b"
|
||||
M.vimcmd(vimcmd, selected)
|
||||
end
|
||||
|
||||
M.buf_del = function(selected)
|
||||
local vimcmd = "bd"
|
||||
M.vimcmd(vimcmd, selected)
|
||||
end
|
||||
|
||||
M.colorscheme = function(selected)
|
||||
if not selected or #selected < 2 then return end
|
||||
vim.cmd("colorscheme " .. selected[2])
|
||||
end
|
||||
|
||||
M.help = function(selected)
|
||||
local vimcmd = "help"
|
||||
M.vimcmd(vimcmd, selected)
|
||||
end
|
||||
|
||||
M.help_vert = function(selected)
|
||||
local vimcmd = "vert help"
|
||||
M.vimcmd(vimcmd, selected)
|
||||
end
|
||||
|
||||
M.help_tab = function(selected)
|
||||
local vimcmd = "tab help"
|
||||
M.vimcmd(vimcmd, selected)
|
||||
end
|
||||
|
||||
M.man = function(selected)
|
||||
local vimcmd = "Man"
|
||||
M.vimcmd(vimcmd, selected)
|
||||
end
|
||||
|
||||
M.man_vert = function(selected)
|
||||
local vimcmd = "vert Man"
|
||||
M.vimcmd(vimcmd, selected)
|
||||
end
|
||||
|
||||
M.man_tab = function(selected)
|
||||
local vimcmd = "tab Man"
|
||||
M.vimcmd(vimcmd, selected)
|
||||
end
|
||||
|
||||
return M
|
@ -0,0 +1,294 @@
|
||||
local utils = require "fzf-lua.utils"
|
||||
local actions = require "fzf-lua.actions"
|
||||
|
||||
-- Clear the default command or it would interfere with our options
|
||||
vim.env.FZF_DEFAULT_OPTS = ''
|
||||
|
||||
local M = {}
|
||||
|
||||
M.win_height = 0.85
|
||||
M.win_width = 0.80
|
||||
M.win_row = 0.30
|
||||
M.win_col = 0.50
|
||||
M.win_border = true
|
||||
M.default_prompt = '> '
|
||||
M.fzf_layout = 'reverse'
|
||||
M.preview_cmd = nil -- auto detect head|bat
|
||||
M.preview_border = 'border'
|
||||
M.preview_wrap = 'nowrap'
|
||||
M.preview_vertical = 'down:45%'
|
||||
M.preview_horizontal = 'right:60%'
|
||||
M.preview_layout = 'flex'
|
||||
M.flip_columns = 120
|
||||
M.bat_theme = nil
|
||||
M.bat_opts = "--italic-text=always --style=numbers,changes --color always"
|
||||
|
||||
M.files = {
|
||||
prompt = '> ',
|
||||
cmd = nil, -- default: auto detect find|fd
|
||||
file_icons = true and pcall(require, "nvim-web-devicons"),
|
||||
color_icons = true,
|
||||
git_icons = true,
|
||||
git_diff_cmd = "git diff --name-status --relative HEAD",
|
||||
git_untracked_cmd = "git ls-files --exclude-standard --others",
|
||||
find_opts = "-type f -printf '%P\n'",
|
||||
fd_opts =
|
||||
[[--color never --type f --hidden --follow ]] ..
|
||||
[[--exclude .git --exclude node_modules --exclude '*.pyc']],
|
||||
actions = {
|
||||
["default"] = actions.file_edit,
|
||||
["ctrl-s"] = actions.file_split,
|
||||
["ctrl-v"] = actions.file_vsplit,
|
||||
["ctrl-t"] = actions.file_tabedit,
|
||||
["ctrl-q"] = actions.file_sel_to_qf,
|
||||
}
|
||||
}
|
||||
|
||||
M.grep = {
|
||||
prompt = 'Rg> ',
|
||||
input_prompt = 'Grep For> ',
|
||||
cmd = nil, -- default: auto detect rg|grep
|
||||
file_icons = true and pcall(require, "nvim-web-devicons"),
|
||||
color_icons = true,
|
||||
git_icons = true,
|
||||
git_diff_cmd = M.files.git_diff_cmd,
|
||||
git_untracked_cmd = M.files.git_untracked_cmd,
|
||||
grep_opts = "--line-number --recursive --color=auto",
|
||||
rg_opts = "--column --line-number --no-heading --color=always --smart-case",
|
||||
actions = {
|
||||
["default"] = actions.file_edit,
|
||||
["ctrl-s"] = actions.file_split,
|
||||
["ctrl-v"] = actions.file_vsplit,
|
||||
["ctrl-t"] = actions.file_tabedit,
|
||||
["ctrl-q"] = actions.file_sel_to_qf,
|
||||
}
|
||||
}
|
||||
|
||||
M.oldfiles = {
|
||||
prompt = 'History> ',
|
||||
file_icons = true and pcall(require, "nvim-web-devicons"),
|
||||
color_icons = true,
|
||||
git_icons = false,
|
||||
git_diff_cmd = M.files.git_diff_cmd,
|
||||
git_untracked_cmd = M.files.git_untracked_cmd,
|
||||
actions = {
|
||||
["default"] = actions.file_edit,
|
||||
["ctrl-s"] = actions.file_split,
|
||||
["ctrl-v"] = actions.file_vsplit,
|
||||
["ctrl-t"] = actions.file_tabedit,
|
||||
["ctrl-q"] = actions.file_sel_to_qf,
|
||||
}
|
||||
}
|
||||
|
||||
M.quickfix = {
|
||||
prompt = 'Quickfix> ',
|
||||
separator = '▏',
|
||||
file_icons = true and pcall(require, "nvim-web-devicons"),
|
||||
color_icons = true,
|
||||
git_icons = false,
|
||||
git_diff_cmd = M.files.git_diff_cmd,
|
||||
git_untracked_cmd = M.files.git_untracked_cmd,
|
||||
actions = {
|
||||
["default"] = actions.file_edit,
|
||||
["ctrl-s"] = actions.file_split,
|
||||
["ctrl-v"] = actions.file_vsplit,
|
||||
["ctrl-t"] = actions.file_tabedit,
|
||||
["ctrl-q"] = actions.file_sel_to_qf,
|
||||
}
|
||||
}
|
||||
|
||||
M.loclist = {
|
||||
prompt = 'Locations> ',
|
||||
separator = '▏',
|
||||
file_icons = true and pcall(require, "nvim-web-devicons"),
|
||||
color_icons = true,
|
||||
git_icons = false,
|
||||
git_diff_cmd = M.files.git_diff_cmd,
|
||||
git_untracked_cmd = M.files.git_untracked_cmd,
|
||||
actions = {
|
||||
["default"] = actions.file_edit,
|
||||
["ctrl-s"] = actions.file_split,
|
||||
["ctrl-v"] = actions.file_vsplit,
|
||||
["ctrl-t"] = actions.file_tabedit,
|
||||
["ctrl-q"] = actions.file_sel_to_qf,
|
||||
}
|
||||
}
|
||||
|
||||
M.git = {
|
||||
prompt = 'GitFiles> ',
|
||||
cmd = "git ls-files --exclude-standard",
|
||||
file_icons = true and pcall(require, "nvim-web-devicons"),
|
||||
color_icons = true,
|
||||
git_icons = true,
|
||||
actions = M.files.actions,
|
||||
}
|
||||
|
||||
M.buffers = {
|
||||
prompt = 'Buffers> ',
|
||||
file_icons = true and pcall(require, "nvim-web-devicons"),
|
||||
color_icons = true,
|
||||
sort_lastused = true,
|
||||
show_all_buffers = true,
|
||||
ignore_current_buffer = false,
|
||||
cwd_only = false,
|
||||
actions = {
|
||||
["default"] = actions.buf_edit,
|
||||
["ctrl-s"] = actions.buf_split,
|
||||
["ctrl-v"] = actions.buf_vsplit,
|
||||
["ctrl-t"] = actions.buf_tabedit,
|
||||
["ctrl-x"] = actions.buf_del,
|
||||
}
|
||||
}
|
||||
|
||||
M.colorschemes = {
|
||||
prompt = 'Colorschemes> ',
|
||||
live_preview = true,
|
||||
actions = {
|
||||
["default"] = actions.colorscheme,
|
||||
},
|
||||
winopts = {
|
||||
win_height = 0.55,
|
||||
win_width = 0.50,
|
||||
},
|
||||
}
|
||||
|
||||
M.helptags = {
|
||||
prompt = 'Help> ',
|
||||
actions = {
|
||||
["default"] = actions.help,
|
||||
["ctrl-s"] = actions.help,
|
||||
["ctrl-v"] = actions.help_vert,
|
||||
["ctrl-t"] = actions.help_tab,
|
||||
},
|
||||
}
|
||||
|
||||
M.manpages = {
|
||||
prompt = 'Man> ',
|
||||
cmd = "man -k .",
|
||||
actions = {
|
||||
["default"] = actions.man,
|
||||
["ctrl-s"] = actions.man,
|
||||
["ctrl-v"] = actions.man_vert,
|
||||
["ctrl-t"] = actions.man_tab,
|
||||
},
|
||||
}
|
||||
|
||||
-- <F2> toggle preview
|
||||
-- <F3> toggle preview text wrap
|
||||
-- <C-f>|<C-b> page down|up
|
||||
-- <C-d>|<C-u> half page down|up
|
||||
-- <S-d>|<S-u> preview page down|up
|
||||
-- <C-a> toggle select-all
|
||||
-- <C-u> clear query
|
||||
-- <C-q> send selected to quicfix
|
||||
-- <A-q> send all to quicfix
|
||||
M.fzf_binds = {
|
||||
'f2:toggle-preview',
|
||||
'f3:toggle-preview-wrap',
|
||||
'shift-down:preview-page-down',
|
||||
'shift-up:preview-page-up',
|
||||
'ctrl-d:half-page-down',
|
||||
'ctrl-u:half-page-up',
|
||||
'ctrl-f:page-down',
|
||||
'ctrl-b:page-up',
|
||||
'ctrl-a:toggle-all',
|
||||
'ctrl-u:clear-query',
|
||||
}
|
||||
|
||||
M.file_icon_colors = {
|
||||
["lua"] = "blue",
|
||||
["vim"] = "green",
|
||||
["sh"] = "cyan",
|
||||
["zsh"] = "cyan",
|
||||
["bash"] = "cyan",
|
||||
["py"] = "green",
|
||||
["md"] = "yellow",
|
||||
["c"] = "blue",
|
||||
["cpp"] = "blue",
|
||||
["h"] = "magenta",
|
||||
["hpp"] = "magenta",
|
||||
["js"] = "blue",
|
||||
["ts"] = "cyan",
|
||||
["tsx"] = "cyan",
|
||||
["css"] = "magenta",
|
||||
["yml"] = "yellow",
|
||||
["yaml"] = "yellow",
|
||||
["json"] = "yellow",
|
||||
["toml"] = "yellow",
|
||||
["conf"] = "yellow",
|
||||
["build"] = "red",
|
||||
["txt"] = "white",
|
||||
["gif"] = "green",
|
||||
["jpg"] = "green",
|
||||
["png"] = "green",
|
||||
["svg"] = "green",
|
||||
["sol"] = "red",
|
||||
["desktop"] = "magenta",
|
||||
}
|
||||
|
||||
M.git_icons = {
|
||||
["M"] = "M",
|
||||
["D"] = "D",
|
||||
["A"] = "A",
|
||||
["?"] = "?"
|
||||
}
|
||||
|
||||
M.git_icon_colors = {
|
||||
["M"] = "yellow",
|
||||
["D"] = "red",
|
||||
["A"] = "green",
|
||||
["?"] = "magenta"
|
||||
}
|
||||
|
||||
M.window_on_create = function()
|
||||
-- Set popup background same as normal windows
|
||||
vim.cmd("set winhl=Normal:Normal")
|
||||
end
|
||||
|
||||
M.winopts = function(opts)
|
||||
|
||||
opts = M.getopts(opts, M, {
|
||||
"win_height", "win_width",
|
||||
"win_row", "win_col", "border",
|
||||
"window_on_create",
|
||||
})
|
||||
|
||||
local height = math.floor(vim.o.lines * opts.win_height)
|
||||
local width = math.floor(vim.o.columns * opts.win_width)
|
||||
local row = math.floor((vim.o.lines - height) * opts.win_row)
|
||||
local col = math.floor((vim.o.columns - width) * opts.win_col)
|
||||
|
||||
return {
|
||||
-- style = 'minimal',
|
||||
height = height, width = width, row = row, col = col,
|
||||
border = opts.win_border,
|
||||
window_on_create = opts.window_on_create
|
||||
}
|
||||
end
|
||||
|
||||
M.preview_window = function()
|
||||
local preview_veritcal = string.format('%s:%s:%s', M.preview_border, M.preview_wrap, M.preview_vertical)
|
||||
local preview_horizontal = string.format('%s:%s:%s', M.preview_border, M.preview_wrap, M.preview_horizontal)
|
||||
if M.preview_layout == "vertical" then
|
||||
return preview_veritcal
|
||||
elseif M.preview_layout == "flex" then
|
||||
return utils._if(vim.o.columns>M.flip_columns, preview_horizontal, preview_veritcal)
|
||||
else
|
||||
return preview_horizontal
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- called to merge caller opts and default config
|
||||
-- before calling a provider method
|
||||
function M.getopts(opts, cfg, keys)
|
||||
if not opts then opts = {} end
|
||||
if keys then
|
||||
for _, k in ipairs(keys) do
|
||||
if opts[k] == nil then opts[k] = cfg[k] end
|
||||
end
|
||||
end
|
||||
return opts
|
||||
end
|
||||
|
||||
return M
|
@ -0,0 +1,199 @@
|
||||
local fzf = require "fzf"
|
||||
local path = require "fzf-lua.path"
|
||||
local utils = require "fzf-lua.utils"
|
||||
local config = require "fzf-lua.config"
|
||||
local actions = require "fzf-lua.actions"
|
||||
|
||||
local M = {}
|
||||
|
||||
M.get_devicon = function(file, ext)
|
||||
local icon = nil
|
||||
if #file > 0 and pcall(require, "nvim-web-devicons") then
|
||||
icon = require'nvim-web-devicons'.get_icon(file, ext)
|
||||
end
|
||||
return utils._if(icon == nil, '', icon)
|
||||
end
|
||||
|
||||
M.preview_cmd = function(opts, cfg)
|
||||
opts = opts or {}
|
||||
opts.filespec = opts.filespec or '{}'
|
||||
opts.preview_cmd = opts.preview_cmd or cfg.preview_cmd
|
||||
opts.preview_args = opts.preview_args or ''
|
||||
opts.bat_opts = opts.bat_opts or cfg.bat_opts
|
||||
local preview = nil
|
||||
if not opts.cwd then opts.cwd = ''
|
||||
elseif #opts.cwd > 0 then
|
||||
opts.cwd = path.add_trailing(opts.cwd)
|
||||
end
|
||||
if opts.preview_cmd and #opts.preview_cmd > 0 then
|
||||
preview = string.format("%s %s -- %s%s", opts.preview_cmd, opts.preview_args, opts.cwd, opts.filespec)
|
||||
elseif vim.fn.executable("bat") == 1 then
|
||||
preview = string.format("bat %s %s -- %s%s", opts.bat_opts, opts.preview_args, opts.cwd, opts.filespec)
|
||||
else
|
||||
preview = string.format("head -n $FZF_PREVIEW_LINES %s -- %s%s", opts.preview_args, opts.cwd, opts.filespec)
|
||||
end
|
||||
if preview ~= nil then
|
||||
-- We use bash to do math on the environment variable, so
|
||||
-- let's make sure this command runs in bash
|
||||
-- preview = "bash -c " .. vim.fn.shellescape(preview)
|
||||
preview = vim.fn.shellescape(preview)
|
||||
end
|
||||
return preview
|
||||
end
|
||||
|
||||
M.build_fzf_cli = function(opts)
|
||||
local cfg = require'fzf-lua.config'
|
||||
opts.prompt = opts.prompt or cfg.default_prompt
|
||||
opts.preview_offset = opts.preview_offset or ''
|
||||
local cli = string.format(
|
||||
[[ --layout=%s --bind=%s --prompt=%s]] ..
|
||||
[[ --preview-window='%s%s' --preview=%s]] ..
|
||||
[[ --expect=%s --ansi --info=inline]] ..
|
||||
[[ %s %s]],
|
||||
cfg.fzf_layout,
|
||||
utils._if(opts.fzf_binds, opts.fzf_binds,
|
||||
vim.fn.shellescape(table.concat(cfg.fzf_binds, ','))),
|
||||
vim.fn.shellescape(opts.prompt),
|
||||
utils._if(opts.preview_window, opts.preview_window, cfg.preview_window()),
|
||||
utils._if(#opts.preview_offset>0, ":"..opts.preview_offset, ''),
|
||||
utils._if(opts.preview, opts.preview, M.preview_cmd(opts, cfg)),
|
||||
utils._if(opts.actions, actions.expect(opts.actions), 'ctrl-s,ctrl-v,ctrl-t'),
|
||||
utils._if(opts.nomulti, '--no-multi', '--multi'),
|
||||
utils._if(opts.cli_args, opts.cli_args, '')
|
||||
)
|
||||
-- print(cli)
|
||||
return cli
|
||||
end
|
||||
|
||||
-- invisible unicode char as icon|git separator
|
||||
-- this way we can split our string by space
|
||||
local nbsp = "\u{00a0}"
|
||||
|
||||
local get_diff_files = function()
|
||||
local diff_files = {}
|
||||
local status = vim.fn.systemlist(config.files.git_diff_cmd)
|
||||
if not utils.shell_error() then
|
||||
for i = 1, #status do
|
||||
local split = vim.split(status[i], " ")
|
||||
diff_files[split[2]] = split[1]
|
||||
end
|
||||
end
|
||||
|
||||
return diff_files
|
||||
end
|
||||
|
||||
local get_untracked_files = function()
|
||||
local untracked_files = {}
|
||||
local status = vim.fn.systemlist(config.files.git_untracked_cmd)
|
||||
if vim.v.shell_error == 0 then
|
||||
for i = 1, #status do
|
||||
untracked_files[status[i]] = "?"
|
||||
end
|
||||
end
|
||||
|
||||
return untracked_files
|
||||
end
|
||||
|
||||
local color_icon = function(icon, ext)
|
||||
if ext then
|
||||
return utils.ansi_codes[config.file_icon_colors[ext] or "dark_grey"](icon)
|
||||
else
|
||||
return utils.ansi_codes[config.git_icon_colors[icon] or "green"](icon)
|
||||
end
|
||||
end
|
||||
|
||||
local get_git_icon = function(file, diff_files, untracked_files)
|
||||
if diff_files and diff_files[file] then
|
||||
return config.git_icons[diff_files[file]]
|
||||
end
|
||||
if untracked_files and untracked_files[file] then
|
||||
return config.git_icons[untracked_files[file]]
|
||||
end
|
||||
return nbsp
|
||||
end
|
||||
|
||||
M.make_entry_file = function(opts, x)
|
||||
local icon
|
||||
local prefix = ''
|
||||
if opts.cwd and #opts.cwd > 0 then
|
||||
x = path.relative(x, opts.cwd)
|
||||
end
|
||||
if opts.file_icons then
|
||||
local extension = path.extension(x)
|
||||
icon = M.get_devicon(x, extension)
|
||||
if opts.color_icons then icon = color_icon(icon, extension) end
|
||||
prefix = prefix .. icon
|
||||
end
|
||||
if opts.git_icons then
|
||||
icon = get_git_icon(x, opts.diff_files, opts.untracked_files)
|
||||
if opts.color_icons then icon = color_icon(icon) end
|
||||
prefix = prefix .. utils._if(#prefix>0, nbsp, '') .. icon
|
||||
end
|
||||
if #prefix > 0 then
|
||||
x = prefix .. " " .. x
|
||||
end
|
||||
return x
|
||||
end
|
||||
|
||||
local function trim_entry(string)
|
||||
string = string:gsub("^[^ ]* ", "")
|
||||
return string
|
||||
end
|
||||
|
||||
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
|
||||
opts.diff_files, opts.untracked_files = nil, nil
|
||||
if not utils.is_git_repo() then opts.git_icons = false end
|
||||
|
||||
if opts.cwd and #opts.cwd > 0 then
|
||||
opts.cwd = vim.fn.expand(opts.cwd)
|
||||
end
|
||||
|
||||
coroutine.wrap(function ()
|
||||
|
||||
if opts.git_icons then
|
||||
opts.diff_files = get_diff_files()
|
||||
opts.untracked_files = get_untracked_files()
|
||||
end
|
||||
|
||||
local has_prefix = opts.file_icons or opts.git_icons
|
||||
if not opts.filespec then
|
||||
opts.filespec = utils._if(has_prefix, "{2}", "{}")
|
||||
end
|
||||
|
||||
local selected = fzf.fzf(opts.fzf_fn,
|
||||
M.build_fzf_cli(opts), config.winopts(opts.winopts))
|
||||
|
||||
if not selected then return end
|
||||
|
||||
if #selected > 1 then
|
||||
for i = 2, #selected do
|
||||
if has_prefix then
|
||||
selected[i] = trim_entry(selected[i])
|
||||
end
|
||||
if opts.cwd and #opts.cwd > 0 then
|
||||
selected[i] = path.join({opts.cwd, selected[i]})
|
||||
end
|
||||
if opts.cb_selected then
|
||||
local cb_ret = opts.cb_selected(opts, selected[i])
|
||||
if cb_ret then selected[i] = cb_ret end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- dump fails after fzf for some odd reason
|
||||
-- functions are still valid as can seen by pairs
|
||||
-- _G.dump(opts.actions)
|
||||
actions.act(opts.actions, selected[1], selected)
|
||||
|
||||
end)()
|
||||
|
||||
end
|
||||
|
||||
return M
|
@ -0,0 +1,192 @@
|
||||
if not pcall(require, "fzf") then
|
||||
return
|
||||
end
|
||||
|
||||
local fzf = require "fzf"
|
||||
local utils = require "fzf-lua.utils"
|
||||
local config = require "fzf-lua.config"
|
||||
|
||||
local M = {}
|
||||
|
||||
local getopt = function(opts, key, expected_type, default)
|
||||
if opts and opts[key] ~= nil then
|
||||
if type(opts[key]) == expected_type then
|
||||
return opts[key]
|
||||
else
|
||||
utils.info(
|
||||
string.format("Expected '%s' for config option '%s', got '%s'",
|
||||
expected_type, key, type(opts[key]))
|
||||
)
|
||||
end
|
||||
elseif default ~= nil then
|
||||
return default
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
local setopt = function(cfg, opts, key, type)
|
||||
cfg[tostring(key)] = getopt(opts, key, type, cfg[tostring(key)])
|
||||
end
|
||||
|
||||
local setopts = function(cfg, opts, tbl)
|
||||
for k, v in pairs(tbl) do
|
||||
setopt(cfg, opts, k, v)
|
||||
end
|
||||
end
|
||||
|
||||
local setopt_tbl = function(cfg, opts, key)
|
||||
if opts and opts[key] then
|
||||
for k, v in pairs(opts[key]) do
|
||||
if not cfg[key] then cfg[key] = {} end
|
||||
cfg[key][k] = v
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function M.setup(opts)
|
||||
setopts(config, opts, {
|
||||
win_height = "number",
|
||||
win_width = "number",
|
||||
win_row = "number",
|
||||
win_col = "number",
|
||||
win_border = "boolean",
|
||||
default_prompt = "string",
|
||||
fzf_layout = "string",
|
||||
fzf_binds = "table",
|
||||
preview_cmd = "string",
|
||||
preview_border = "string",
|
||||
preview_wrap = "string",
|
||||
preview_vertical = "string",
|
||||
preview_horizontal = "string",
|
||||
preview_layout = "string",
|
||||
flip_columns = "number",
|
||||
window_on_create = "function",
|
||||
bat_theme = "string",
|
||||
bat_opts = "string",
|
||||
})
|
||||
setopts(config.files, opts.files, {
|
||||
prompt = "string",
|
||||
cmd = "string",
|
||||
git_icons = "boolean",
|
||||
file_icons = "boolean",
|
||||
color_icons = "boolean",
|
||||
fd_opts = "string",
|
||||
find_opts = "string",
|
||||
git_diff_cmd = "string",
|
||||
git_untracked_cmd = "string",
|
||||
})
|
||||
setopts(config.grep, opts.grep, {
|
||||
prompt = "string",
|
||||
input_prompt = "string",
|
||||
cmd = "string",
|
||||
git_icons = "boolean",
|
||||
file_icons = "boolean",
|
||||
color_icons = "boolean",
|
||||
rg_opts = "string",
|
||||
grep_opts = "string",
|
||||
git_diff_cmd = "string",
|
||||
git_untracked_cmd = "string",
|
||||
})
|
||||
setopts(config.oldfiles, opts.oldfiles, {
|
||||
prompt = "string",
|
||||
git_icons = "boolean",
|
||||
file_icons = "boolean",
|
||||
color_icons = "boolean",
|
||||
git_diff_cmd = "string",
|
||||
git_untracked_cmd = "string",
|
||||
cwd_only = "boolean",
|
||||
include_current_session = "boolean",
|
||||
})
|
||||
setopts(config.quickfix, opts.quickfix, {
|
||||
prompt = "string",
|
||||
cwd = "string",
|
||||
separator = "string",
|
||||
git_icons = "boolean",
|
||||
file_icons = "boolean",
|
||||
color_icons = "boolean",
|
||||
git_diff_cmd = "string",
|
||||
git_untracked_cmd = "string",
|
||||
})
|
||||
setopts(config.loclist, opts.loclist, {
|
||||
prompt = "string",
|
||||
cwd = "string",
|
||||
separator = "string",
|
||||
git_icons = "boolean",
|
||||
file_icons = "boolean",
|
||||
color_icons = "boolean",
|
||||
git_diff_cmd = "string",
|
||||
git_untracked_cmd = "string",
|
||||
})
|
||||
setopts(config.git, opts.git, {
|
||||
prompt = "string",
|
||||
cmd = "string",
|
||||
git_icons = "boolean",
|
||||
file_icons = "boolean",
|
||||
color_icons = "boolean",
|
||||
})
|
||||
setopts(config.buffers, opts.buffers, {
|
||||
prompt = "string",
|
||||
git_prompt = "string",
|
||||
file_icons = "boolean",
|
||||
color_icons = "boolean",
|
||||
sort_lastused = "boolean",
|
||||
show_all_buffers = "boolean",
|
||||
ignore_current_buffer = "boolean",
|
||||
cwd_only = "boolean",
|
||||
})
|
||||
setopts(config.colorschemes, opts.colorschemes, {
|
||||
prompt = "string",
|
||||
live_preview = "boolean",
|
||||
post_reset_cb = "function",
|
||||
})
|
||||
setopts(config.manpages, opts.manpages, {
|
||||
prompt = "string",
|
||||
cmd = "string",
|
||||
})
|
||||
setopts(config.helptags, opts.helptags, {
|
||||
prompt = "string",
|
||||
})
|
||||
-- table overrides without losing defaults
|
||||
for _, k in ipairs({
|
||||
"git", "files", "oldfiles", "buffers",
|
||||
"grep", "quickfix", "loclist",
|
||||
"colorschemes", "helptags", "manpages",
|
||||
}) do
|
||||
setopt_tbl(config[k], opts[k], "actions")
|
||||
setopt_tbl(config[k], opts[k], "winopts")
|
||||
end
|
||||
setopt_tbl(config, opts, "git_icons")
|
||||
setopt_tbl(config, opts, "git_icon_colors")
|
||||
setopt_tbl(config, opts, "file_icon_colors")
|
||||
-- override the bat preview theme if set by caller
|
||||
if config.bat_theme and #config.bat_theme > 0 then
|
||||
vim.env.BAT_THEME = config.bat_theme
|
||||
end
|
||||
-- reset default window opts if set by user
|
||||
fzf.default_window_options = config.winopts()
|
||||
end
|
||||
|
||||
-- we usually send winopts with every fzf.fzf call
|
||||
-- but set default window options just in case
|
||||
fzf.default_window_options = config.winopts()
|
||||
|
||||
M.fzf_files = require'fzf-lua.core'.fzf_files
|
||||
M.files = require'fzf-lua.providers.files'.files
|
||||
M.grep = require'fzf-lua.providers.grep'.grep
|
||||
M.live_grep = require'fzf-lua.providers.grep'.live_grep
|
||||
M.grep_last = require'fzf-lua.providers.grep'.grep_last
|
||||
M.grep_cword = require'fzf-lua.providers.grep'.grep_cword
|
||||
M.grep_cWORD = require'fzf-lua.providers.grep'.grep_cWORD
|
||||
M.grep_visual = require'fzf-lua.providers.grep'.grep_visual
|
||||
M.grep_curbuf = require'fzf-lua.providers.grep'.grep_curbuf
|
||||
M.git_files = require'fzf-lua.providers.files'.git_files
|
||||
M.oldfiles = require'fzf-lua.providers.oldfiles'.oldfiles
|
||||
M.quickfix = require'fzf-lua.providers.quickfix'.quickfix
|
||||
M.loclist = require'fzf-lua.providers.quickfix'.loclist
|
||||
M.buffers = require'fzf-lua.providers.buffers'.buffers
|
||||
M.help_tags = require'fzf-lua.providers.helptags'.helptags
|
||||
M.man_pages = require'fzf-lua.providers.manpages'.manpages
|
||||
M.colorschemes = require'fzf-lua.providers.colorschemes'.colorschemes
|
||||
|
||||
return M
|
@ -0,0 +1,99 @@
|
||||
local M = {}
|
||||
|
||||
M.separator = function()
|
||||
return '/'
|
||||
end
|
||||
|
||||
M.tail = (function()
|
||||
local os_sep = M.separator()
|
||||
local match_string = '[^' .. os_sep .. ']*$'
|
||||
|
||||
return function(path)
|
||||
return string.match(path, match_string)
|
||||
end
|
||||
end)()
|
||||
|
||||
function M.to_matching_str(path)
|
||||
return path:gsub('(%-)', '(%%-)'):gsub('(%.)', '(%%.)'):gsub('(%_)', '(%%_)')
|
||||
end
|
||||
|
||||
function M.join(paths)
|
||||
return table.concat(paths, M.separator())
|
||||
end
|
||||
|
||||
function M.split(path)
|
||||
return path:gmatch('[^'..M.separator()..']+'..M.separator()..'?')
|
||||
end
|
||||
|
||||
---Get the basename of the given path.
|
||||
---@param path string
|
||||
---@return string
|
||||
function M.basename(path)
|
||||
path = M.remove_trailing(path)
|
||||
local i = path:match("^.*()" .. M.separator())
|
||||
if not i then return path end
|
||||
return path:sub(i + 1, #path)
|
||||
end
|
||||
|
||||
function M.extension(path)
|
||||
-- path = M.basename(path)
|
||||
-- return path:match(".+%.(.*)")
|
||||
-- search for the first dotten string part up to space
|
||||
-- then match anything after the dot up to ':/\.'
|
||||
path = path:match("(%.[^ :\t\x1b]+)")
|
||||
if not path then return path end
|
||||
return path:match("^.*%.([^ :\\/]+)")
|
||||
end
|
||||
|
||||
---Get the path to the parent directory of the given path. Returns `nil` if the
|
||||
---path has no parent.
|
||||
---@param path string
|
||||
---@param remove_trailing boolean
|
||||
---@return string|nil
|
||||
function M.parent(path, remove_trailing)
|
||||
path = " " .. M.remove_trailing(path)
|
||||
local i = path:match("^.+()" .. M.separator())
|
||||
if not i then return nil end
|
||||
path = path:sub(2, i)
|
||||
if remove_trailing then
|
||||
path = M.remove_trailing(path)
|
||||
end
|
||||
return path
|
||||
end
|
||||
|
||||
---Get a path relative to another path.
|
||||
---@param path string
|
||||
---@param relative_to string
|
||||
---@return string
|
||||
function M.relative(path, relative_to)
|
||||
local p, _ = path:gsub("^" .. M.to_matching_str(M.add_trailing(relative_to)), "")
|
||||
return p
|
||||
end
|
||||
|
||||
function M.add_trailing(path)
|
||||
if path:sub(-1) == M.separator() then
|
||||
return path
|
||||
end
|
||||
|
||||
return path..M.separator()
|
||||
end
|
||||
|
||||
function M.remove_trailing(path)
|
||||
local p, _ = path:gsub(M.separator()..'$', '')
|
||||
return p
|
||||
end
|
||||
|
||||
function M.shorten(path, max_length)
|
||||
if string.len(path) > max_length - 1 then
|
||||
path = path:sub(string.len(path) - max_length + 1, string.len(path))
|
||||
local i = path:match("()" .. M.separator())
|
||||
if not i then
|
||||
return "…" .. path
|
||||
end
|
||||
return "…" .. path:sub(i, -1)
|
||||
else
|
||||
return path
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
@ -0,0 +1,148 @@
|
||||
if not pcall(require, "fzf") then
|
||||
return
|
||||
end
|
||||
|
||||
local action = require("fzf.actions").action
|
||||
local core = require "fzf-lua.core"
|
||||
local path = require "fzf-lua.path"
|
||||
local utils = require "fzf-lua.utils"
|
||||
local config = require "fzf-lua.config"
|
||||
local actions = require "fzf-lua.actions"
|
||||
local fn, api = vim.fn, vim.api
|
||||
|
||||
local M = {}
|
||||
|
||||
local function getbufnumber(line)
|
||||
return tonumber(string.match(line, "%[(%d+)"))
|
||||
end
|
||||
|
||||
local function getfilename(line)
|
||||
return string.match(line, "%[.*%] (.+)")
|
||||
end
|
||||
|
||||
M.buffers = function(opts)
|
||||
|
||||
opts = config.getopts(opts, config.buffers, {
|
||||
"prompt", "actions", "winopts",
|
||||
"file_icons", "color_icons", "sort_lastused",
|
||||
"show_all_buffers", "ignore_current_buffer",
|
||||
"cwd_only",
|
||||
})
|
||||
|
||||
local act = action(function (items, fzf_lines, _)
|
||||
-- only preview first item
|
||||
local item = items[1]
|
||||
local buf = getbufnumber(item)
|
||||
if api.nvim_buf_is_loaded(buf) then
|
||||
return api.nvim_buf_get_lines(buf, 0, fzf_lines, false)
|
||||
else
|
||||
local name = getfilename(item)
|
||||
if fn.filereadable(name) ~= 0 then
|
||||
return fn.readfile(name, "", fzf_lines)
|
||||
end
|
||||
return "UNLOADED: " .. name
|
||||
end
|
||||
end)
|
||||
|
||||
coroutine.wrap(function ()
|
||||
local items = {}
|
||||
|
||||
local bufnrs = vim.tbl_filter(function(b)
|
||||
if 1 ~= vim.fn.buflisted(b) then
|
||||
return false
|
||||
end
|
||||
-- only hide unloaded buffers if opts.show_all_buffers is false, keep them listed if true or nil
|
||||
if opts.show_all_buffers == false and not vim.api.nvim_buf_is_loaded(b) then
|
||||
return false
|
||||
end
|
||||
if opts.ignore_current_buffer and b == vim.api.nvim_get_current_buf() then
|
||||
return false
|
||||
end
|
||||
if opts.cwd_only and not string.find(vim.api.nvim_buf_get_name(b), vim.loop.cwd(), 1, true) then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end, vim.api.nvim_list_bufs())
|
||||
if not next(bufnrs) then return end
|
||||
|
||||
local header_line = false
|
||||
local buffers = {}
|
||||
for _, bufnr in ipairs(bufnrs) do
|
||||
local flag = bufnr == vim.fn.bufnr('') and '%' or (bufnr == vim.fn.bufnr('#') and '#' or ' ')
|
||||
|
||||
local element = {
|
||||
bufnr = bufnr,
|
||||
flag = flag,
|
||||
info = vim.fn.getbufinfo(bufnr)[1],
|
||||
}
|
||||
|
||||
if opts.sort_lastused and (flag == "#" or flag == "%") then
|
||||
if flag == "%" then header_line = true end
|
||||
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
|
||||
|
||||
for _, buf in pairs(buffers) do
|
||||
-- local hidden = buf.info.hidden == 1 and 'h' or 'a'
|
||||
local hidden = ''
|
||||
local readonly = vim.api.nvim_buf_get_option(buf.bufnr, 'readonly') and '=' or ' '
|
||||
local changed = buf.info.changed == 1 and '+' or ' '
|
||||
local flags = hidden .. readonly .. changed
|
||||
local leftbr = utils.ansi_codes.clear('[')
|
||||
local rightbr = utils.ansi_codes.clear(']')
|
||||
local bufname = string.format("%s:%s",
|
||||
utils._if(#buf.info.name>0, path.relative(buf.info.name, vim.loop.cwd()), "[No Name]"),
|
||||
utils._if(buf.info.lnum>0, buf.info.lnum, ""))
|
||||
if buf.flag == '%' then
|
||||
flags = utils.ansi_codes.red(buf.flag) .. flags
|
||||
bufname = utils.ansi_codes.green(bufname)
|
||||
leftbr = utils.ansi_codes.green('[')
|
||||
rightbr = utils.ansi_codes.green(']')
|
||||
elseif buf.flag == '#' then
|
||||
flags = utils.ansi_codes.cyan(buf.flag) .. flags
|
||||
else
|
||||
flags = " " .. flags
|
||||
end
|
||||
local bufnrstr = string.format("%s%s%s", leftbr,
|
||||
utils.ansi_codes.yellow(string.format(buf.bufnr)), rightbr)
|
||||
local buficon = ''
|
||||
if opts.file_icons then
|
||||
local extension = path.extension(buf.info.name)
|
||||
buficon = core.get_devicon(buf.info.name, extension)
|
||||
if opts.color_icons then
|
||||
buficon = utils.ansi_codes[config.file_icon_colors[extension] or "dark_grey"](buficon) .. " "
|
||||
end
|
||||
end
|
||||
local item_str = string.format("%s%s %s %s%s",
|
||||
utils._if(buf.bufnr>9, '' , ' '),
|
||||
bufnrstr, flags, buficon, bufname)
|
||||
table.insert(items, item_str)
|
||||
end
|
||||
|
||||
local selected = require("fzf").fzf(items,
|
||||
core.build_fzf_cli({
|
||||
prompt = opts.prompt,
|
||||
preview = act,
|
||||
actions = opts.actions,
|
||||
cli_args = utils._if(header_line and not opts.ignore_current_buffer,
|
||||
'--header-lines=1', '')
|
||||
}),
|
||||
config.winopts(opts))
|
||||
|
||||
if not selected then return end
|
||||
|
||||
if #selected > 1 then
|
||||
for i = 2, #selected do
|
||||
selected[i] = tostring(getbufnumber(selected[i]))
|
||||
end
|
||||
end
|
||||
|
||||
actions.act(opts.actions, selected[1], selected)
|
||||
|
||||
end)()
|
||||
end
|
||||
|
||||
return M
|
@ -0,0 +1,64 @@
|
||||
if not pcall(require, "fzf") then
|
||||
return
|
||||
end
|
||||
|
||||
local fzf = require "fzf"
|
||||
local action = require("fzf.actions").action
|
||||
local core = require "fzf-lua.core"
|
||||
local utils = require "fzf-lua.utils"
|
||||
local config = require "fzf-lua.config"
|
||||
local actions = require "fzf-lua.actions"
|
||||
|
||||
local function get_current_colorscheme()
|
||||
if vim.g.colors_name then
|
||||
return vim.g.colors_name
|
||||
else
|
||||
return 'default'
|
||||
end
|
||||
end
|
||||
|
||||
local M = {}
|
||||
|
||||
M.colorschemes = function(opts)
|
||||
|
||||
opts = config.getopts(opts, config.colorschemes, {
|
||||
"prompt", "actions", "winopts", "live_preview", "post_reset_cb",
|
||||
})
|
||||
|
||||
coroutine.wrap(function ()
|
||||
local prev_act = action(function (args)
|
||||
if opts.live_preview and args then
|
||||
local colorscheme = args[1]
|
||||
vim.cmd("colorscheme " .. colorscheme)
|
||||
end
|
||||
end)
|
||||
|
||||
local current_colorscheme = get_current_colorscheme()
|
||||
local current_background = vim.o.background
|
||||
local colors = vim.list_extend(opts.colors or {}, vim.fn.getcompletion('', 'color'))
|
||||
local selected = fzf.fzf(colors,
|
||||
core.build_fzf_cli({
|
||||
prompt = opts.prompt,
|
||||
preview = prev_act, preview_window = 'right:0',
|
||||
actions = opts.actions,
|
||||
nomulti = true,
|
||||
}),
|
||||
config.winopts(opts.winopts))
|
||||
|
||||
if not selected then
|
||||
vim.o.background = current_background
|
||||
vim.cmd("colorscheme " .. current_colorscheme)
|
||||
vim.o.background = current_background
|
||||
else
|
||||
actions.act(opts.actions, selected[1], selected)
|
||||
end
|
||||
|
||||
if opts.post_reset_cb then
|
||||
opts.post_reset_cb()
|
||||
end
|
||||
|
||||
end)()
|
||||
|
||||
end
|
||||
|
||||
return M
|
@ -0,0 +1,66 @@
|
||||
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_files_cmd = function(opts)
|
||||
if opts.cmd and #opts.cmd>0 then
|
||||
return opts.cmd
|
||||
end
|
||||
local command = nil
|
||||
if vim.fn.executable("fd") == 1 then
|
||||
if not opts.cwd or #opts.cwd == 0 then
|
||||
command = string.format('fd %s', opts.fd_opts)
|
||||
else
|
||||
command = string.format('fd %s . %s', opts.fd_opts,
|
||||
vim.fn.shellescape(opts.cwd))
|
||||
end
|
||||
else
|
||||
command = string.format('find %s %s',
|
||||
utils._if(opts.cwd and #opts.cwd>0, vim.fn.shellescape(opts.cwd), '.'),
|
||||
opts.find_opts)
|
||||
end
|
||||
return command
|
||||
end
|
||||
|
||||
M.files = function(opts)
|
||||
opts = config.getopts(opts, config.files, {
|
||||
"cmd", "prompt", "actions", "winopts",
|
||||
"file_icons", "color_icons", "git_icons",
|
||||
"fd_opts", "find_opts",
|
||||
})
|
||||
|
||||
|
||||
local command = get_files_cmd(opts)
|
||||
|
||||
opts.fzf_fn = fzf_helpers.cmd_line_transformer(command,
|
||||
function(x)
|
||||
return core.make_entry_file(opts, x)
|
||||
end)
|
||||
|
||||
return core.fzf_files(opts)
|
||||
end
|
||||
|
||||
M.git_files = function(opts)
|
||||
local output = vim.fn.systemlist("git status")
|
||||
if utils.shell_error() then
|
||||
utils.info(unpack(output))
|
||||
return
|
||||
end
|
||||
opts = config.getopts(opts, config.git, {
|
||||
"cmd", "prompt", "actions", "winopts",
|
||||
"file_icons", "color_icons", "git_icons",
|
||||
})
|
||||
-- opts.cmd sets this to "git ls-files"
|
||||
return M.files(opts)
|
||||
end
|
||||
|
||||
return M
|
@ -0,0 +1,193 @@
|
||||
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)
|
||||
|
||||
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
|
||||
|
||||
return string.format("%s -- %s %s", command,
|
||||
utils._if(opts.last_search and #opts.last_search>0,
|
||||
vim.fn.shellescape(opts.last_search), "{q}"),
|
||||
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.repeat_last_search == true then
|
||||
opts.search = config.grep.last_search
|
||||
end
|
||||
-- save the next search as last_search so we
|
||||
-- let the caller have an option to run the
|
||||
-- same search again
|
||||
-- print("1", opts.last_search, opts.search)
|
||||
if not opts.search or #opts.search == 0 then
|
||||
config.grep.last_search = vim.fn.input(opts.input_prompt)
|
||||
else
|
||||
config.grep.last_search = opts.search
|
||||
end
|
||||
opts.last_search = config.grep.last_search
|
||||
if not opts.last_search or #opts.last_search == 0 then
|
||||
utils.info("Please provider valid search string")
|
||||
return
|
||||
end
|
||||
|
||||
local command = get_grep_cmd(opts)
|
||||
|
||||
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)
|
||||
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",
|
||||
})
|
||||
|
||||
-- resetting last_search will return
|
||||
-- {q} placeholder in our command
|
||||
opts.last_search = opts.search
|
||||
local initial_command = get_grep_cmd(opts)
|
||||
opts.last_search = nil
|
||||
local reload_command = get_grep_cmd(opts) .. " || true"
|
||||
|
||||
--[[ local fzf_binds = utils.tbl_deep_clone(config.fzf_binds)
|
||||
table.insert(fzf_binds, string.format("change:reload:%s", reload_command))
|
||||
opts.fzf_binds = vim.fn.shellescape(table.concat(fzf_binds, ',')) ]]
|
||||
|
||||
opts.cli_args = "--delimiter='[: ]' " ..
|
||||
string.format("--phony --query=%s --bind=%s",
|
||||
utils._if(opts.search and #opts.search>0, opts.search, [['']]),
|
||||
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:
|
||||
-- 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)
|
||||
end
|
||||
|
||||
M.grep_last = function(opts)
|
||||
if not opts then opts = {} end
|
||||
opts.repeat_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
|
@ -0,0 +1,125 @@
|
||||
if not pcall(require, "fzf") then
|
||||
return
|
||||
end
|
||||
|
||||
local fzf = require "fzf"
|
||||
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 actions = require "fzf-lua.actions"
|
||||
|
||||
|
||||
local M = {}
|
||||
|
||||
local fzf_function = function (cb)
|
||||
local opts = {}
|
||||
opts.lang = config.helptags.lang or vim.o.helplang
|
||||
opts.fallback = utils._if(config.helptags.fallback ~= nil, config.helptags.fallback, true)
|
||||
|
||||
local langs = vim.split(opts.lang, ',', true)
|
||||
if opts.fallback and not vim.tbl_contains(langs, 'en') then
|
||||
table.insert(langs, 'en')
|
||||
end
|
||||
local langs_map = {}
|
||||
for _, lang in ipairs(langs) do
|
||||
langs_map[lang] = true
|
||||
end
|
||||
|
||||
local tag_files = {}
|
||||
local function add_tag_file(lang, file)
|
||||
if langs_map[lang] then
|
||||
if tag_files[lang] then
|
||||
table.insert(tag_files[lang], file)
|
||||
else
|
||||
tag_files[lang] = {file}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local help_files = {}
|
||||
local all_files = vim.fn.globpath(vim.o.runtimepath, 'doc/*', 1, 1)
|
||||
for _, fullpath in ipairs(all_files) do
|
||||
local file = path.tail(fullpath)
|
||||
if file == 'tags' then
|
||||
add_tag_file('en', fullpath)
|
||||
elseif file:match('^tags%-..$') then
|
||||
local lang = file:sub(-2)
|
||||
add_tag_file(lang, fullpath)
|
||||
else
|
||||
help_files[file] = fullpath
|
||||
end
|
||||
end
|
||||
|
||||
local add_tag = function(t, fzf_cb, co)
|
||||
--[[ local tag = string.format("%-58s\t%s",
|
||||
utils.ansi_codes.blue(t.name),
|
||||
utils._if(t.name and #t.name>0, path.basename(t.name), '')) ]]
|
||||
local tag = utils.ansi_codes.magenta(t.name)
|
||||
fzf_cb(tag, function()
|
||||
coroutine.resume(co)
|
||||
end)
|
||||
end
|
||||
|
||||
coroutine.wrap(function ()
|
||||
local co = coroutine.running()
|
||||
local tags_map = {}
|
||||
local delimiter = string.char(9)
|
||||
for _, lang in ipairs(langs) do
|
||||
for _, file in ipairs(tag_files[lang] or {}) do
|
||||
local lines = vim.split(utils.read_file(file), '\n', true)
|
||||
for _, line in ipairs(lines) do
|
||||
-- TODO: also ignore tagComment starting with ';'
|
||||
if not line:match'^!_TAG_' then
|
||||
local fields = vim.split(line, delimiter, true)
|
||||
if #fields == 3 and not tags_map[fields[1]] then
|
||||
add_tag({
|
||||
name = fields[1],
|
||||
filename = help_files[fields[2]],
|
||||
cmd = fields[3],
|
||||
lang = lang,
|
||||
}, cb, co)
|
||||
tags_map[fields[1]] = true
|
||||
-- pause here until we call coroutine.resume()
|
||||
coroutine.yield()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
-- done
|
||||
-- cb(nil)
|
||||
end)()
|
||||
end
|
||||
|
||||
|
||||
M.helptags = function(opts)
|
||||
|
||||
opts = config.getopts(opts, config.helptags, {
|
||||
"prompt", "actions", "winopts",
|
||||
})
|
||||
|
||||
coroutine.wrap(function ()
|
||||
|
||||
-- local prev_act = action(function (args) end)
|
||||
|
||||
local selected = fzf.fzf(fzf_function,
|
||||
core.build_fzf_cli({
|
||||
prompt = opts.prompt,
|
||||
-- preview = prev_act,
|
||||
preview_window = 'right:0',
|
||||
actions = opts.actions,
|
||||
cli_args = "--nth 1",
|
||||
nomulti = true,
|
||||
}),
|
||||
config.winopts(opts.winopts))
|
||||
|
||||
if not selected then return end
|
||||
|
||||
actions.act(opts.actions, selected[1], selected)
|
||||
|
||||
end)()
|
||||
|
||||
end
|
||||
|
||||
return M
|
@ -0,0 +1,63 @@
|
||||
if not pcall(require, "fzf") then
|
||||
return
|
||||
end
|
||||
|
||||
local fzf = require "fzf"
|
||||
local fzf_helpers = require("fzf.helpers")
|
||||
local core = require "fzf-lua.core"
|
||||
local utils = require "fzf-lua.utils"
|
||||
local config = require "fzf-lua.config"
|
||||
local actions = require "fzf-lua.actions"
|
||||
|
||||
|
||||
local M = {}
|
||||
|
||||
local function getmanpage(line)
|
||||
-- match until comma or space
|
||||
return string.match(line, "[^, ]+")
|
||||
end
|
||||
|
||||
M.manpages = function(opts)
|
||||
|
||||
opts = config.getopts(opts, config.manpages, {
|
||||
"prompt", "actions", "winopts", "cmd",
|
||||
})
|
||||
|
||||
coroutine.wrap(function ()
|
||||
|
||||
-- local prev_act = action(function (args) end)
|
||||
|
||||
local fzf_fn = fzf_helpers.cmd_line_transformer(opts.cmd, function(x)
|
||||
-- split by first occurence of ' - ' (spaced hyphen)
|
||||
local man, desc = x:match("^(.-) %- (.*)$")
|
||||
return string.format("%-45s %s",
|
||||
utils.ansi_codes.red(man), desc)
|
||||
end)
|
||||
|
||||
local selected = fzf.fzf(fzf_fn,
|
||||
core.build_fzf_cli({
|
||||
prompt = opts.prompt,
|
||||
-- preview = prev_act,
|
||||
preview_window = 'right:0',
|
||||
actions = opts.actions,
|
||||
cli_args = "--tiebreak begin --nth 1,2",
|
||||
nomulti = true,
|
||||
}),
|
||||
config.winopts(opts.winopts))
|
||||
|
||||
if not selected then return end
|
||||
|
||||
if #selected > 1 then
|
||||
for i = 2, #selected do
|
||||
selected[i] = getmanpage(selected[i])
|
||||
print(selected[i])
|
||||
end
|
||||
end
|
||||
|
||||
actions.act(opts.actions, selected[1], selected)
|
||||
|
||||
end)()
|
||||
|
||||
end
|
||||
|
||||
return M
|
@ -0,0 +1,70 @@
|
||||
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 = {}
|
||||
|
||||
M.oldfiles = function(opts)
|
||||
opts = config.getopts(opts, config.oldfiles, {
|
||||
"prompt", "actions", "winopts",
|
||||
"file_icons", "color_icons", "git_icons",
|
||||
"include_current_session", "cwd_only",
|
||||
})
|
||||
|
||||
local current_buffer = vim.api.nvim_get_current_buf()
|
||||
local current_file = vim.api.nvim_buf_get_name(current_buffer)
|
||||
local results = {}
|
||||
|
||||
if opts.include_current_session then
|
||||
for _, buffer in ipairs(vim.split(vim.fn.execute(':buffers! t'), "\n")) do
|
||||
local match = tonumber(string.match(buffer, '%s*(%d+)'))
|
||||
if match then
|
||||
local file = vim.api.nvim_buf_get_name(match)
|
||||
if vim.loop.fs_stat(file) and match ~= current_buffer then
|
||||
table.insert(results, file)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for _, file in ipairs(vim.v.oldfiles) do
|
||||
if vim.loop.fs_stat(file) and not vim.tbl_contains(results, file) and file ~= current_file then
|
||||
table.insert(results, file)
|
||||
end
|
||||
end
|
||||
|
||||
if opts.cwd_only then
|
||||
opts.cwd = vim.loop.cwd()
|
||||
local cwd = opts.cwd
|
||||
cwd = cwd:gsub([[\]],[[\\]])
|
||||
results = vim.tbl_filter(function(file)
|
||||
return vim.fn.matchstrpos(file, cwd)[2] ~= -1
|
||||
end, results)
|
||||
end
|
||||
|
||||
opts.fzf_fn = function (cb)
|
||||
for _, x in ipairs(results) do
|
||||
x = core.make_entry_file(opts, x)
|
||||
cb(x, function(err)
|
||||
if err then return end
|
||||
-- cb(nil) -- to close the pipe to fzf, this removes the loading
|
||||
-- indicator in fzf
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
--[[ opts.cb_selected = function(_, x)
|
||||
print("o:", x)
|
||||
end ]]
|
||||
|
||||
return core.fzf_files(opts)
|
||||
end
|
||||
|
||||
return M
|
@ -0,0 +1,89 @@
|
||||
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 quickfix_run = function(opts, cfg, locations)
|
||||
if not locations then return {} end
|
||||
local results = {}
|
||||
for _, entry in ipairs(locations) do
|
||||
local filename = entry.filename or vim.api.nvim_buf_get_name(entry.bufnr)
|
||||
table.insert(results, string.format("%s:%s:%s:\t%s",
|
||||
filename, --utils.ansi_codes.magenta(filename),
|
||||
utils.ansi_codes.green(tostring(entry.lnum)),
|
||||
utils.ansi_codes.blue(tostring(entry.col)),
|
||||
entry.text))
|
||||
end
|
||||
|
||||
opts = config.getopts(opts, cfg, {
|
||||
"cwd", "prompt", "actions", "winopts",
|
||||
"file_icons", "color_icons", "git_icons",
|
||||
"separator"
|
||||
})
|
||||
|
||||
opts.fzf_fn = function (cb)
|
||||
for _, x in ipairs(results) do
|
||||
x = core.make_entry_file(opts, x)
|
||||
cb(x, function(err)
|
||||
if err then return end
|
||||
-- cb(nil) -- to close the pipe to fzf, this removes the loading
|
||||
-- indicator in fzf
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
--[[ opts.cb_selected = function(_, x)
|
||||
return x
|
||||
end ]]
|
||||
|
||||
opts.cli_args = "--delimiter='[: \\t]'"
|
||||
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"
|
||||
return core.fzf_files(opts)
|
||||
end
|
||||
|
||||
M.quickfix = function(opts)
|
||||
local locations = vim.fn.getqflist()
|
||||
if vim.tbl_isempty(locations) then
|
||||
utils.info("Quickfix list is empty.")
|
||||
return
|
||||
end
|
||||
|
||||
return quickfix_run(opts, config.quickfix, locations)
|
||||
end
|
||||
|
||||
M.loclist = function(opts)
|
||||
local locations = vim.fn.getloclist(0)
|
||||
|
||||
for _, value in pairs(locations) do
|
||||
value.filename = vim.api.nvim_buf_get_name(value.bufnr)
|
||||
end
|
||||
|
||||
if vim.tbl_isempty(locations) then
|
||||
utils.info("Location list is empty.")
|
||||
return
|
||||
end
|
||||
|
||||
return quickfix_run(opts, config.loclist, locations)
|
||||
end
|
||||
|
||||
return M
|
@ -0,0 +1,174 @@
|
||||
-- help to inspect results, e.g.:
|
||||
-- ':lua _G.dump(vim.fn.getwininfo())'
|
||||
function _G.dump(...)
|
||||
local objects = vim.tbl_map(vim.inspect, { ... })
|
||||
print(unpack(objects))
|
||||
end
|
||||
|
||||
local M = {}
|
||||
|
||||
M._if = function(bool, a, b)
|
||||
if bool then
|
||||
return a
|
||||
else
|
||||
return b
|
||||
end
|
||||
end
|
||||
|
||||
function M._echo_multiline(msg)
|
||||
for _, s in ipairs(vim.fn.split(msg, "\n")) do
|
||||
vim.cmd("echom '" .. s:gsub("'", "''").."'")
|
||||
end
|
||||
end
|
||||
|
||||
function M.info(msg)
|
||||
vim.cmd('echohl Directory')
|
||||
M._echo_multiline("[Fzf-lua] " .. msg)
|
||||
vim.cmd('echohl None')
|
||||
end
|
||||
|
||||
function M.warn(msg)
|
||||
vim.cmd('echohl WarningMsg')
|
||||
M._echo_multiline("[Fzf-lua] " .. msg)
|
||||
vim.cmd('echohl None')
|
||||
end
|
||||
|
||||
function M.err(msg)
|
||||
vim.cmd('echohl ErrorMsg')
|
||||
M._echo_multiline("[Fzf-lua] " .. msg)
|
||||
vim.cmd('echohl None')
|
||||
end
|
||||
|
||||
function M.shell_error()
|
||||
return vim.v.shell_error ~= 0
|
||||
end
|
||||
|
||||
function M.is_git_repo()
|
||||
vim.fn.system("git status")
|
||||
return M._if(M.shell_error(), false, true)
|
||||
end
|
||||
|
||||
M.read_file = function(filepath)
|
||||
local fd = vim.loop.fs_open(filepath, "r", 438)
|
||||
if fd == nil then return '' end
|
||||
local stat = assert(vim.loop.fs_fstat(fd))
|
||||
if stat.type ~= 'file' then return '' end
|
||||
local data = assert(vim.loop.fs_read(fd, stat.size, 0))
|
||||
assert(vim.loop.fs_close(fd))
|
||||
return data
|
||||
end
|
||||
|
||||
M.read_file_async = function(filepath, callback)
|
||||
vim.loop.fs_open(filepath, "r", 438, function(err_open, fd)
|
||||
if err_open then
|
||||
print("We tried to open this file but couldn't. We failed with following error message: " .. err_open)
|
||||
return
|
||||
end
|
||||
vim.loop.fs_fstat(fd, function(err_fstat, stat)
|
||||
assert(not err_fstat, err_fstat)
|
||||
if stat.type ~= 'file' then return callback('') end
|
||||
vim.loop.fs_read(fd, stat.size, 0, function(err_read, data)
|
||||
assert(not err_read, err_read)
|
||||
vim.loop.fs_close(fd, function(err_close)
|
||||
assert(not err_close, err_close)
|
||||
return callback(data)
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
|
||||
function M.tbl_deep_clone(t)
|
||||
if not t then return end
|
||||
local clone = {}
|
||||
|
||||
for k, v in pairs(t) do
|
||||
if type(v) == "table" then
|
||||
clone[k] = M.tbl_deep_clone(v)
|
||||
else
|
||||
clone[k] = v
|
||||
end
|
||||
end
|
||||
|
||||
return clone
|
||||
end
|
||||
|
||||
function M.tbl_length(T)
|
||||
local count = 0
|
||||
for _ in pairs(T) do count = count + 1 end
|
||||
return count
|
||||
end
|
||||
|
||||
function M.tbl_has(table, key)
|
||||
return table[key] ~= nil
|
||||
end
|
||||
|
||||
function M.tbl_or(key, tbl1, tbl2)
|
||||
if tbl1[key] ~= nil then return tbl1[key]
|
||||
else return tbl2[key] end
|
||||
end
|
||||
|
||||
function M.tbl_concat(...)
|
||||
local result = {}
|
||||
local n = 0
|
||||
|
||||
for _, t in ipairs({...}) do
|
||||
for i, v in ipairs(t) do
|
||||
result[n + i] = v
|
||||
end
|
||||
n = n + #t
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
function M.tbl_pack(...)
|
||||
return {n=select('#',...); ...}
|
||||
end
|
||||
|
||||
function M.tbl_unpack(t, i, j)
|
||||
return unpack(t, i or 1, j or t.n or #t)
|
||||
end
|
||||
|
||||
M.ansi_codes = {}
|
||||
M.ansi_colors = {
|
||||
clear = "\x1b[0m",
|
||||
bold = "\x1b[1m",
|
||||
black = "\x1b[0;30m",
|
||||
red = "\x1b[0;31m",
|
||||
green = "\x1b[0;32m",
|
||||
yellow = "\x1b[0;33m",
|
||||
blue = "\x1b[0;34m",
|
||||
magenta = "\x1b[0;35m",
|
||||
cyan = "\x1b[0;36m",
|
||||
grey = "\x1b[0;90m",
|
||||
dark_grey = "\x1b[0;97m",
|
||||
white = "\x1b[0;98m",
|
||||
}
|
||||
|
||||
for color, escseq in pairs(M.ansi_colors) do
|
||||
M.ansi_codes[color] = function(string)
|
||||
if string == nil or #string == 0 then return '' end
|
||||
return escseq .. string .. M.ansi_colors.clear
|
||||
end
|
||||
end
|
||||
|
||||
function M.get_visual_selection()
|
||||
-- must exit visual mode or program croaks
|
||||
-- :visual leaves ex-mode back to normal mode
|
||||
-- use 'gv' to reselect the text
|
||||
vim.cmd[[visual]]
|
||||
local _, csrow, cscol, _ = unpack(vim.fn.getpos("'<"))
|
||||
local _, cerow, cecol, _ = unpack(vim.fn.getpos("'>"))
|
||||
local lines = vim.fn.getline(csrow, cerow)
|
||||
-- local n = cerow-csrow+1
|
||||
local n = M.tbl_length(lines)
|
||||
if n <= 0 then return '' end
|
||||
lines[n] = string.sub(lines[n], 1, cecol)
|
||||
lines[1] = string.sub(lines[1], cscol)
|
||||
print(n, csrow, cscol, cerow, cecol, table.concat(lines, "\n"))
|
||||
return table.concat(lines, "\n")
|
||||
end
|
||||
|
||||
return M
|
@ -0,0 +1,8 @@
|
||||
if exists('g:loaded_fzf_lua') | finish | endif
|
||||
|
||||
if !has('nvim-0.5')
|
||||
echohl Error
|
||||
echomsg "Fzf-lua is only available for Neovim versions 0.5 and above"
|
||||
echohl clear
|
||||
finish
|
||||
endif
|
Loading…
Reference in New Issue