From 23034bb022b28fb26e07532ad99ecdd6681095f6 Mon Sep 17 00:00:00 2001 From: bhagwan Date: Thu, 12 May 2022 16:13:45 -0700 Subject: [PATCH] feat: new git provider: 'git_stash' (closes #410) --- README.md | 14 ++++++++++++++ doc/fzf-lua.txt | 14 ++++++++++++++ lua/fzf-lua/actions.lua | 13 +++++++++++++ lua/fzf-lua/config.lua | 18 ++++++++++++++++++ lua/fzf-lua/init.lua | 1 + lua/fzf-lua/providers/git.lua | 29 +++++++++++++++++++++++++++++ 6 files changed, 89 insertions(+) diff --git a/README.md b/README.md index c8c86f4..6c1e189 100644 --- a/README.md +++ b/README.md @@ -179,6 +179,7 @@ vim.api.nvim_set_keymap('n', '', | `git_commits` | git commit log (project) | | `git_bcommits` | git commit log (buffer) | | `git_branches` | git branches | +| `git_stash` | git stash | ### LSP | Command | List | @@ -546,6 +547,19 @@ require'fzf-lua'.setup { ["default"] = actions.git_switch, }, }, + stash = { + prompt = 'Stash> ', + cmd = "git --no-pager stash list", + preview = "git --no-pager stash show --patch --color {1}", + actions = { + ["default"] = actions.git_stash_apply, + ["ctrl-x"] = { actions.git_stash_drop, actions.resume }, + }, + fzf_opts = { + ["--no-multi"] = '', + ['--delimiter'] = "'[:]'", + }, + }, icons = { ["M"] = { icon = "M", color = "yellow" }, ["D"] = { icon = "D", color = "red" }, diff --git a/doc/fzf-lua.txt b/doc/fzf-lua.txt index 2f13d5f..d4b8d1c 100644 --- a/doc/fzf-lua.txt +++ b/doc/fzf-lua.txt @@ -209,6 +209,7 @@ GIT *fzf-lua-git* | `git_commits` | git commit log (project) | | `git_bcommits` | git commit log (buffer) | | `git_branches` | git branches | +| `git_stash` | git stash | @@ -591,6 +592,19 @@ Consult the list below for available settings: ["default"] = actions.git_switch, }, }, + stash = { + prompt = 'Stash> ', + cmd = "git --no-pager stash list", + preview = "git --no-pager stash show --patch --color {1}", + actions = { + ["default"] = actions.git_stash_apply, + ["ctrl-x"] = { actions.git_stash_drop, actions.resume }, + }, + fzf_opts = { + ["--no-multi"] = '', + ['--delimiter'] = "'[:]'", + }, + }, icons = { ["M"] = { icon = "M", color = "yellow" }, ["D"] = { icon = "D", color = "red" }, diff --git a/lua/fzf-lua/actions.lua b/lua/fzf-lua/actions.lua index 7b7a2b1..53c5c60 100644 --- a/lua/fzf-lua/actions.lua +++ b/lua/fzf-lua/actions.lua @@ -503,6 +503,19 @@ M.git_reset = function(selected, opts) git_exec(selected, opts, cmd) end +M.git_stash_drop = function(selected, opts) + local cmd = path.git_cwd({"git", "stash", "drop"}, opts) + git_exec(selected, opts, cmd) +end + +M.git_stash_apply = function(selected, opts) + if vim.fn.input("Apply " .. #selected .. " stash(es)? [y/n] ") == "y" then + local cmd = path.git_cwd({"git", "stash", "apply"}, opts) + git_exec(selected, opts, cmd) + vim.cmd("e!") + end +end + M.git_buf_edit = function(selected, opts) local cmd = path.git_cwd({"git", "show"}, opts) local git_root = path.git_root(opts, true) diff --git a/lua/fzf-lua/config.lua b/lua/fzf-lua/config.lua index ee2ecdd..19dd1f3 100644 --- a/lua/fzf-lua/config.lua +++ b/lua/fzf-lua/config.lua @@ -253,6 +253,22 @@ M.globals.git = { ["default"] = actions.git_switch, }, }, + stash = { + prompt = 'Stash> ', + cmd = "git --no-pager stash list", + preview = "git --no-pager stash show --patch --color {1}", + actions = { + ["default"] = actions.git_stash_apply, + ["ctrl-x"] = { actions.git_stash_drop, actions.resume }, + }, + fzf_opts = { + -- TODO: multiselect requires more work as dropping + -- a stash changes the stash index causing an error + -- when the next stash is attempted a drop + ["--no-multi"] = '', + ['--delimiter'] = "'[:]'", + }, + }, icons = { ["M"] = { icon = "M", color = "yellow" }, ["D"] = { icon = "D", color = "red" }, @@ -867,6 +883,8 @@ M._action_to_helpstr = { [actions.git_stage] = "git-stage", [actions.git_unstage] = "git-unstage", [actions.git_reset] = "git-reset", + [actions.git_stash_drop] = "git-stash-drop", + [actions.git_stash_apply] = "git-stash-apply", [actions.git_buf_edit] = "git-buffer-edit", [actions.git_buf_tabedit] = "git-buffer-tabedit", [actions.git_buf_split] = "git-buffer-split", diff --git a/lua/fzf-lua/init.lua b/lua/fzf-lua/init.lua index d305a49..3b0c0f3 100644 --- a/lua/fzf-lua/init.lua +++ b/lua/fzf-lua/init.lua @@ -93,6 +93,7 @@ M.lgrep_curbuf = require'fzf-lua.providers.grep'.lgrep_curbuf M.grep_project = require'fzf-lua.providers.grep'.grep_project M.git_files = require'fzf-lua.providers.git'.files M.git_status = require'fzf-lua.providers.git'.status +M.git_stash = require'fzf-lua.providers.git'.stash M.git_commits = require'fzf-lua.providers.git'.commits M.git_bcommits = require'fzf-lua.providers.git'.bcommits M.git_branches = require'fzf-lua.providers.git'.branches diff --git a/lua/fzf-lua/providers/git.lua b/lua/fzf-lua/providers/git.lua index 91281a8..5610e56 100644 --- a/lua/fzf-lua/providers/git.lua +++ b/lua/fzf-lua/providers/git.lua @@ -136,4 +136,33 @@ M.branches = function(opts) return git_cmd(opts) end +M.stash = function(opts) + opts = config.normalize_opts(opts, config.globals.git.stash) + if not opts then return end + + if opts.preview then + opts.preview = vim.fn.shellescape(path.git_cwd(opts.preview, opts)) + end + + if opts.fzf_opts['--header'] == nil then + opts.fzf_opts['--header'] = vim.fn.shellescape((':: %s to drop selected stash(es)') + :format(utils.ansi_codes.yellow(""))) + end + + opts.cmd = libuv.spawn_nvim_fzf_cmd( + { cmd = opts.cmd, cwd = opts.cwd }, + function(x) + local stash, rest = x:match("([^:]+)(.*)") + if stash then + stash = utils.ansi_codes.yellow(stash) + stash = stash:gsub("{%d+}", function(s) + return ("%s"):format(utils.ansi_codes.green(tostring(s))) + end) + end + return (not stash or not rest) and x or stash .. rest + end) + + return git_cmd(opts) +end + return M