'git_status' preview rework, stage|unstage with <left>|<right> (#239)

main
bhagwan 2 years ago
parent aec049eaa6
commit b2aee6f1d3

@ -366,8 +366,9 @@ require'fzf-lua'.setup {
args = nil,
},
git_diff = {
cmd = "git diff",
args = "--color",
cmd_deleted = "git diff --color HEAD --",
cmd_modified = "git diff --color HEAD",
cmd_untracked = "git diff --color --no-index /dev/null",
-- pager = "delta", -- if you have `delta` installed
},
man = {
@ -421,12 +422,21 @@ require'fzf-lua'.setup {
color_icons = true, -- colorize file|git icons
},
status = {
prompt = 'GitStatus ',
cmd = "git status -s",
previewer = "git_diff",
file_icons = true,
git_icons = true,
color_icons = true,
prompt = 'GitStatus ',
cmd = "git status -s",
previewer = "git_diff",
file_icons = true,
git_icons = true,
color_icons = true,
actions = {
["default"] = actions.file_edit_or_qf,
["ctrl-s"] = actions.file_split,
["ctrl-v"] = actions.file_vsplit,
["ctrl-t"] = actions.file_tabedit,
["alt-q"] = actions.file_sel_to_qf,
["right"] = { actions.git_unstage, actions.resume },
["left"] = { actions.git_stage, actions.resume },
},
},
commits = {
prompt = 'Commits ',

@ -400,8 +400,9 @@ Consult the list below for available settings:
args = nil,
},
git_diff = {
cmd = "git diff",
args = "--color",
cmd_deleted = "git diff --color HEAD --",
cmd_modified = "git diff --color HEAD",
cmd_untracked = "git diff --color --no-index /dev/null",
-- pager = "delta", -- if you have `delta` installed
},
man = {
@ -455,12 +456,21 @@ Consult the list below for available settings:
color_icons = true, -- colorize file|git icons
},
status = {
prompt = 'GitStatus ',
cmd = "git status -s",
previewer = "git_diff",
file_icons = true,
git_icons = true,
color_icons = true,
prompt = 'GitStatus ',
cmd = "git status -s",
previewer = "git_diff",
file_icons = true,
git_icons = true,
color_icons = true,
actions = {
["default"] = actions.file_edit_or_qf,
["ctrl-s"] = actions.file_split,
["ctrl-v"] = actions.file_vsplit,
["ctrl-t"] = actions.file_tabedit,
["alt-q"] = actions.file_sel_to_qf,
["right"] = { actions.git_unstage, actions.resume },
["left"] = { actions.git_stage, actions.resume },
},
},
commits = {
prompt = 'Commits ',

@ -411,6 +411,30 @@ M.git_checkout = function(selected, opts)
end
end
local git_exec = function(selected, opts, cmd)
for _, e in ipairs(selected) do
local file = path.relative(path.entry_to_file(e, opts.cwd).path, opts.cwd)
local _cmd = vim.deepcopy(cmd)
table.insert(_cmd, file)
local output = utils.io_systemlist(_cmd)
if utils.shell_error() then
utils.err(unpack(output))
-- elseif not vim.tbl_isempty(output) then
-- utils.info(unpack(output))
end
end
end
M.git_stage = function(selected, opts)
local cmd = path.git_cwd({"git", "add", "--"}, opts.cwd)
git_exec(selected, opts, cmd)
end
M.git_unstage = function(selected, opts)
local cmd = path.git_cwd({"git", "reset", "--"}, opts.cwd)
git_exec(selected, opts, cmd)
end
M.git_buf_edit = function(selected, opts)
local cmd = path.git_cwd({"git", "show"}, opts.cwd)
local git_root = path.git_root(opts.cwd, true)

@ -142,8 +142,9 @@ M.globals = {
_ctor = previewers.fzf.head,
},
git_diff = {
cmd = "git diff",
args = "--color",
cmd_deleted = "git diff --color HEAD --",
cmd_modified = "git diff --color HEAD",
cmd_untracked = "git diff --color --no-index /dev/null",
_ctor = previewers.fzf.git_diff,
},
man = {
@ -198,7 +199,15 @@ M.globals.git = {
file_icons = true and M._has_devicons,
color_icons = true,
git_icons = true,
actions = M.globals.files.actions,
actions = {
["default"] = actions.file_edit_or_qf,
["ctrl-s"] = actions.file_split,
["ctrl-v"] = actions.file_vsplit,
["ctrl-t"] = actions.file_tabedit,
["alt-q"] = actions.file_sel_to_qf,
["right"] = { actions.git_unstage, actions.resume },
["left"] = { actions.git_stage, actions.resume },
},
},
commits = {
prompt = 'Commits> ',

@ -142,7 +142,9 @@ Previewer.git_diff = Previewer.cmd_async:extend()
function Previewer.git_diff:new(o, opts)
Previewer.git_diff.super.new(self, o, opts)
self.cmd = path.git_cwd(self.cmd, opts.cwd)
self.cmd_deleted = path.git_cwd(o.cmd_deleted, opts.cwd)
self.cmd_modified = path.git_cwd(o.cmd_modified, opts.cwd)
self.cmd_untracked = path.git_cwd(o.cmd_untracked, opts.cwd)
self.pager = o.pager
return self
end
@ -151,21 +153,21 @@ function Previewer.git_diff:cmdline(o)
o = o or {}
local act = shell.preview_action_cmd(function(items)
local is_deleted = items[1]:match("D"..utils.nbsp) ~= nil
local is_untracked = items[1]:match("[?RAC]"..utils.nbsp) ~= nil
local is_modified = items[1]:match("[MRA]"..utils.nbsp) ~= nil
local is_untracked = items[1]:match("[%?C]"..utils.nbsp) ~= nil
local file = path.entry_to_file(items[1], not self.relative and self.opts.cwd)
local cmd = self.cmd
local args = self.args
local cmd = nil
if is_modified then cmd = self.cmd_modified
elseif is_deleted then cmd = self.cmd_deleted
elseif is_untracked then cmd = self.cmd_untracked end
local pager = ""
if self.pager and #self.pager>0 and
vim.fn.executable(self.pager:match("[^%s]+")) == 1 then
pager = '| ' .. self.pager
end
if is_untracked then args = args .. " --no-index /dev/null" end
if is_deleted then
cmd = self.cmd:gsub("diff", "show HEAD:")
cmd = string.format('%s"%s"', cmd, path.relative(file.path, self.opts.cwd))
else
cmd = string.format('%s %s %s %s', cmd, args, vim.fn.shellescape(file.path), pager)
cmd = string.format('%s %s %s', cmd, vim.fn.shellescape(file.path), pager)
if self.opts.debug then
print("[DEBUG]: "..cmd.."\n")
end
-- uncomment to see the command in the preview window
-- cmd = vim.fn.shellescape(cmd)

@ -26,17 +26,47 @@ M.status = function(opts)
if opts.preview then
opts.preview = vim.fn.shellescape(path.git_cwd(opts.preview, opts.cwd))
end
-- we don't need git icons since we get them
-- as part of our `git status -s`
opts.git_icons = false
if not opts.no_header then
local stage = utils.ansi_codes.yellow("<left>")
local unstage = utils.ansi_codes.yellow("<right>")
opts.fzf_opts['--header'] = vim.fn.shellescape(
('+ - :: %s to stage, %s to unstage'):format(stage, unstage))
end
local function git_iconify(x)
local icon = x
local git_icon = config.globals.git.icons[x]
if git_icon then
icon = git_icon.icon
if opts.color_icons then
icon = utils.ansi_codes[git_icon.color or "dark_grey"](icon)
end
end
return icon
end
local contents = libuv.spawn_nvim_fzf_cmd(opts,
function(x)
-- greedy match anything after last space
local f = x:match("[^ ]*$")
if f:sub(#f) == '"' then
-- `git status -s` wraps
-- spaced files with quotes
f = x:sub(1, #x-1)
f = f:match('[^"]*$')
-- unrecognizable format, return
if not x or #x<4 then return x end
-- `man git-status`
-- we are guaranteed format of: XY <text>
-- spaced files are wrapped with quotes
-- remove both git markers and quotes
local f1, f2 = x:sub(4):gsub('"', ""), nil
-- renames spearate files with '->'
if f1:match("%s%->%s") then
f1, f2 = f1:match("(.*)%s%->%s(.*)")
end
return core.make_entry_file(opts, f)
f1 = f1 and core.make_entry_file(opts, f1)
f2 = f2 and core.make_entry_file(opts, f2)
local staged = git_iconify(x:sub(1,1):gsub("?", " "))
local unstaged = git_iconify(x:sub(2,2))
local entry = ("%s%s%s%s%s"):format(
staged, utils.nbsp, unstaged, utils.nbsp .. utils.nbsp,
(f2 and ("%s -> %s"):format(f1, f2) or f1))
return entry
end,
function(o)
return core.make_entry_preprocess(o)

Loading…
Cancel
Save