'git_xxx' now supports 'cwd' option (closes issue #82)

main
bhagwan 3 years ago
parent e3e6d2643b
commit 7b9fe4495e

@ -157,6 +157,7 @@ nnoremap <c-P> <cmd>lua require('fzf-lua').files()<CR>
|`lsp_implementations`|Implementations|
|`lsp_document_symbols`|Document Symbols|
|`lsp_workspace_symbols`|Workspace Symbols|
|`lsp_live_workspace_symbols`|Workspace Symbols (live query)|
|`lsp_code_actions`|Code Actions|
|`lsp_document_diagnostics`|Document Diagnostics|
|`lsp_workspace_diagnostics`|Workspace Diagnostics|

@ -18,7 +18,7 @@ M.expect = function(actions)
return nil
end
M.act = function(actions, selected)
M.act = function(actions, selected, opts)
if not actions or not selected then return end
local action = "default"
-- if there are no actions besides default
@ -28,7 +28,7 @@ M.act = function(actions, selected)
if actions and utils.tbl_length(actions) > 1 and
#selected>1 and #selected[1]>0 then action = selected[1] end
if actions[action] then
actions[action](selected)
actions[action](selected, opts)
end
end
@ -216,14 +216,15 @@ M.man_tab = function(selected)
end
M.git_switch = function(selected)
M.git_switch = function(selected, opts)
local cmd = path.git_cwd("git switch ", opts.cwd)
-- remove anything past space
local branch = selected[1]:match("[^ ]+")
-- do nothing for active branch
if branch:find("%*") ~= nil then return end
local args = ""
if branch:find("/") ~= nil then args = "--detach " end
local output = vim.fn.systemlist("git switch " .. args .. branch)
local output = vim.fn.systemlist(cmd .. args .. branch)
if utils.shell_error() then
utils.err(unpack(output))
else
@ -232,12 +233,14 @@ M.git_switch = function(selected)
end
end
M.git_checkout = function(selected)
M.git_checkout = function(selected, opts)
local cmd_checkout = path.git_cwd("git checkout ", opts.cwd)
local cmd_cur_commit = path.git_cwd("git rev-parse --short HEAD", opts.cwd)
local commit_hash = selected[1]:match("[^ ]+")
if vim.fn.input("Checkout commit " .. commit_hash .. "? [y/n] ") == "y" then
local current_commit = vim.fn.systemlist("git rev-parse --short HEAD")
local current_commit = vim.fn.systemlist(cmd_cur_commit)
if(commit_hash == current_commit) then return end
local output = vim.fn.systemlist("git checkout " .. commit_hash)
local output = vim.fn.systemlist(cmd_checkout .. commit_hash)
if utils.shell_error() then
utils.err(unpack(output))
else
@ -247,14 +250,15 @@ M.git_checkout = function(selected)
end
end
M.git_buf_edit = function(selected)
M.git_buf_edit = function(selected, opts)
local cmd = path.git_cwd("git show ", opts.cwd)
-- there's an empty string in position 1 for some reason?
table.remove(selected,1)
local win = vim.api.nvim_get_current_win()
local buffer_filetype = vim.bo.filetype
local file = path.relative(vim.fn.expand("%"), vim.loop.cwd())
local commit_hash = selected[1]:match("[^ ]+")
local git_file_contents = vim.fn.systemlist("git show " .. commit_hash .. ":" .. file)
local git_file_contents = vim.fn.systemlist(cmd .. commit_hash .. ":" .. file)
local buf = vim.api.nvim_create_buf(true, false)
local file_name = string.gsub(file,"%.","[" .. commit_hash .. "]%.")
vim.api.nvim_buf_set_lines(buf,0,0,true,git_file_contents)
@ -265,19 +269,19 @@ M.git_buf_edit = function(selected)
vim.api.nvim_win_set_buf(win, buf)
end
M.git_buf_tabedit = function(selected)
M.git_buf_tabedit = function(selected, opts)
vim.cmd('tab split')
M.git_buf_edit(selected)
M.git_buf_edit(selected, opts)
end
M.git_buf_split = function(selected)
M.git_buf_split = function(selected, opts)
vim.cmd('split')
M.git_buf_edit(selected)
M.git_buf_edit(selected, opts)
end
M.git_buf_vsplit = function(selected)
M.git_buf_vsplit = function(selected, opts)
vim.cmd('vsplit')
M.git_buf_edit(selected)
M.git_buf_edit(selected, opts)
end
return M

@ -1,4 +1,3 @@
local utils = require "fzf-lua.utils"
local actions = require "fzf-lua.actions"
-- Clear the default command or it would interfere with our options
@ -100,7 +99,7 @@ M.globals = {
git_diff = {
cmd = "git diff",
args = "--color",
_new = function() return require 'fzf-lua.previewer'.cmd_async end,
_new = function() return require 'fzf-lua.previewer'.git_diff end,
},
builtin = {
title = true,

@ -97,9 +97,10 @@ M.build_fzf_cli = function(opts, debug_print)
return cli
end
local get_diff_files = function()
local get_diff_files = function(opts)
local diff_files = {}
local status = vim.fn.systemlist(config.globals.files.git_diff_cmd)
local status = vim.fn.systemlist(path.git_cwd(
config.globals.files.git_diff_cmd, opts.cwd))
if not utils.shell_error() then
for i = 1, #status do
local icon, file = status[i]:match("^([MUDAR])%s+(.*)")
@ -110,12 +111,14 @@ local get_diff_files = function()
return diff_files
end
local get_untracked_files = function()
local get_untracked_files = function(opts)
local untracked_files = {}
local status = vim.fn.systemlist(config.globals.files.git_untracked_cmd)
local status = vim.fn.systemlist(path.git_cwd(
config.globals.files.git_untracked_cmd, opts.cwd))
if vim.v.shell_error == 0 then
for i = 1, #status do
untracked_files[status[i]] = "?"
local file = status[i]
untracked_files[file] = "?"
end
end
@ -207,7 +210,7 @@ M.fzf_files = function(opts)
-- reset git tracking
opts.diff_files, opts.untracked_files = nil, nil
if opts.git_icons and not utils.is_git_repo() then opts.git_icons = false end
if opts.git_icons and not path.is_git_repo(opts.cwd, true) then opts.git_icons = false end
if opts.cwd and #opts.cwd > 0 then
opts.cwd = vim.fn.expand(opts.cwd)
@ -220,8 +223,8 @@ M.fzf_files = function(opts)
end
if opts.git_icons then
opts.diff_files = get_diff_files()
opts.untracked_files = get_untracked_files()
opts.diff_files = get_diff_files(opts)
opts.untracked_files = get_untracked_files(opts)
end
local has_prefix = opts.file_icons or opts.git_icons or opts.lsp_icons

@ -153,4 +153,23 @@ function M.entry_to_file(entry, cwd)
}
end
function M.git_cwd(cmd, cwd)
if not cwd then return cmd end
cwd = vim.fn.expand(cwd)
local arg_cwd = (" --git-dir=%s --work-tree=%s "):format(
vim.fn.shellescape(M.join({cwd, ".git"})),
vim.fn.shellescape(cwd))
return cmd:gsub("^git ", "git " .. arg_cwd)
end
function M.is_git_repo(cwd, noerr)
local cmd = M.git_cwd("git rev-parse --is-inside-work-tree", cwd)
local output = vim.fn.systemlist(cmd)
if utils.shell_error() then
if not noerr then utils.info(unpack(output)) end
return false
end
return true
end
return M

@ -10,6 +10,7 @@ Previewer.cmd = {}
Previewer.bat = {}
Previewer.cmd_async = {}
Previewer.bat_async = {}
Previewer.git_diff = {}
Previewer.buffer = {}
-- Constructors call on Previewer.<o>()
@ -154,4 +155,13 @@ function Previewer.bat_async:cmdline(o)
return act
end
function Previewer.git_diff:new(o, opts)
self = setmetatable(Previewer.cmd(o, opts), {
__index = vim.tbl_deep_extend("keep",
self, Previewer.cmd_async, Previewer.base
)})
self.cmd = path.git_cwd(self.cmd, opts.cwd)
return self
end
return Previewer

@ -11,25 +11,15 @@ local actions = require "fzf-lua.actions"
local M = {}
-- code duplication, we don't use the utils version of this
-- as it doesn't print the "not in a git repo" error
local function is_git_repo()
local output = vim.fn.systemlist("git rev-parse --is-inside-work-tree")
if utils.shell_error() then
utils.info(unpack(output))
return false
end
return true
end
local function git_version()
local out = vim.fn.system("git --version")
return out:match("(%d+.%d+).")
end
M.files = function(opts)
if not is_git_repo() then return end
opts = config.normalize_opts(opts, config.globals.git.files)
if not path.is_git_repo(opts.cwd) then return end
opts.cmd = path.git_cwd(opts.cmd, opts.cwd)
opts.fzf_fn = fzf_helpers.cmd_line_transformer(opts.cmd,
function(x)
return core.make_entry_file(opts, x)
@ -38,9 +28,12 @@ M.files = function(opts)
end
M.status = function(opts)
if not is_git_repo() then return end
opts = config.normalize_opts(opts, config.globals.git.status)
if opts.preview then opts.preview = vim.fn.shellescape(opts.preview) end
if not path.is_git_repo(opts.cwd) then return end
if opts.preview then
opts.preview = vim.fn.shellescape(path.git_cwd(opts.preview, opts.cwd))
end
opts.cmd = path.git_cwd(opts.cmd, opts.cwd)
opts.fzf_fn = fzf_helpers.cmd_line_transformer(opts.cmd,
function(x)
-- greedy match anything after last space
@ -51,19 +44,20 @@ M.status = function(opts)
end
local function git_cmd(opts)
if not is_git_repo() then return end
if not path.is_git_repo(opts.cwd) then return end
opts.cmd = path.git_cwd(opts.cmd, opts.cwd)
coroutine.wrap(function ()
opts.fzf_fn = fzf_helpers.cmd_line_transformer(opts.cmd,
function(x) return x end)
local selected = core.fzf(opts, opts.fzf_fn)
if not selected then return end
actions.act(opts.actions, selected)
actions.act(opts.actions, selected, opts)
end)()
end
M.commits = function(opts)
opts = config.normalize_opts(opts, config.globals.git.commits)
opts.preview = vim.fn.shellescape(opts.preview)
opts.preview = vim.fn.shellescape(path.git_cwd(opts.preview, opts.cwd))
return git_cmd(opts)
end
@ -76,13 +70,13 @@ M.bcommits = function(opts)
if git_ver and tonumber(git_ver) >= 2.31 then
opts.preview = opts.preview .. " --rotate-to=" .. vim.fn.shellescape(file)
end
opts.preview = vim.fn.shellescape(opts.preview)
opts.preview = vim.fn.shellescape(path.git_cwd(opts.preview, opts.cwd))
return git_cmd(opts)
end
M.branches = function(opts)
opts = config.normalize_opts(opts, config.globals.git.branches)
opts._preview = opts.preview
opts._preview = path.git_cwd(opts.preview, opts.cwd)
opts.preview = fzf_helpers.choices_to_shell_cmd_previewer(function(items)
local branch = items[1]:gsub("%*", "") -- remove the * from current branch
if branch:find("%)") ~= nil then

@ -61,12 +61,6 @@ function M.shell_error()
return vim.v.shell_error ~= 0
end
function M.is_git_repo()
-- can also use: "git rev-parse is-inside-work-tree"
vim.fn.system("git rev-parse --git-dir")
return M._if(M.shell_error(), false, true)
end
function M.rg_escape(str)
if not str then return str end
-- [(~'"\/$?'`*&&||;[]<>)]

Loading…
Cancel
Save