diff --git a/lua/custom/plugins/fugitive.lua b/lua/custom/plugins/fugitive.lua index 1732799..7e547f6 100644 --- a/lua/custom/plugins/fugitive.lua +++ b/lua/custom/plugins/fugitive.lua @@ -2,14 +2,6 @@ return { { -- Git related plugins 'tpope/vim-fugitive', - dependencies = { - { - 'rbong/vim-flog', - lazy = true, - cmd = { 'Flogsplit' }, - }, - 'idanarye/vim-merginal', - }, config = function() -- Switch in fugitive.vim status window with the current one vim.keymap.set('n', 'gs', 'Gedit :', { desc = '[G]it [S]tatus' }) @@ -19,10 +11,6 @@ return { vim.keymap.set('n', 'gP', 'Git push', { desc = '[G]it [P]ush' }) -- Pull changes vim.keymap.set('n', 'gp', 'Git pull', { desc = '[G]it [P]ull' }) - -- Open history graph - vim.keymap.set('n', 'gl', 'Flogsplitwincmd kq', { desc = '[G]it [L]og' }) - -- Open branch manager - vim.keymap.set('n', 'gm', 'Merginal', { desc = '[G]it [M]erginal' }) end, }, } diff --git a/lua/custom/utils/telescope.lua b/lua/custom/utils/telescope.lua new file mode 100644 index 0000000..90f5b7f --- /dev/null +++ b/lua/custom/utils/telescope.lua @@ -0,0 +1,127 @@ +local M = {} + +-- builtin telescope modules +local utils = require 'telescope.utils' +local actions = require 'telescope.actions' +local builtin = require 'telescope.builtin' +local action_state = require 'telescope.actions.state' + +--- Reference: [telescope.actions.git_apply_stash](https://github.com/nvim-telescope/telescope.nvim/blob/master/lua/telescope/actions/init.lua#L587) +--- @param prompt_bufnr number: The prompt buffer number from Telescope. +local function git_apply_stash(prompt_bufnr) + local selection = action_state.get_selected_entry() + if selection == nil then + utils.__warn_no_selection 'actions.git_apply_stash' + return + end + actions.close(prompt_bufnr) + -- Remove unwanted '--index' flag from command + local _, ret, stderr = utils.get_os_command_output { 'git', 'stash', 'apply', selection.value } + if ret == 0 then + utils.notify('actions.git_apply_stash', { + msg = string.format("applied: '%s' ", selection.value), + level = 'INFO', + }) + else + utils.notify('actions.git_apply_stash', { + ---@diagnostic disable-next-line: param-type-mismatch + msg = string.format("Error when applying: %s. Git returned: '%s'", selection.value, table.concat(stderr, ' ')), + level = 'ERROR', + }) + end +end + +--- Custom function to match any unique characters inside a pattern. +--- @param str string: The input string to scan. +--- @param pat string: The pattern to search for. +--- @param arr table: The output table to append to. +function M.match_to_list(str, pat, arr) + string.gsub(str, pat, function(match) + -- do not insert existing entry into index list + if not vim.list_contains(arr, match) then + table.insert(arr, match) + end + end) +end + +--- Get all selected entries in the Telescope picker and extract stash indices. +--- @param prompt_bufnr number: The prompt buffer number from Telescope. +--- @return table|false: A list of stash indices or false if nothing is selected. +function M.get_stash_selections(prompt_bufnr) + local picker = action_state.get_current_picker(prompt_bufnr) + local selection = picker:get_multi_selection() + + local stashes = {} + -- scan all multi_selection entries + for _, entry in ipairs(selection) do + local value = entry.value + M.match_to_list(value, '{(.-)}', stashes) + end + + -- scan single selected entry + local entry = action_state.get_selected_entry() + if entry == nil and #stashes == 0 then + vim.notify( + ---@diagnostic disable-next-line: param-type-mismatch + string.format('WARN [%s]: Nothing currently selected', 'git_drop_stash'), + vim.log.levels.WARN, + { title = 'telescope.nvim' } + ) + return false + end + M.match_to_list(entry.value, '{(.-)}', stashes) + + return stashes +end + +--- Drop git stashes by their indices. +--- @param stashes table: A list of stash indices to drop. +function M.git_drop_stash(stashes) + local success = {} + for idx = #stashes, 1, -1 do + -- execute git command in os + -- reference: https://github.com/nvim-telescope/telescope.nvim/blob/master/lua/telescope/actions/init.lua#L594 + local _, ret, stderr = utils.get_os_command_output { 'git', 'stash', 'drop', string.format('stash@{%d}', stashes[idx]) } + if ret ~= 0 then + -- extracted from telescope.utils.notify: + vim.notify( + ---@diagnostic disable-next-line: param-type-mismatch + string.format("Error when dropping: stash@{%s}. Git returned: '%s'", stashes[idx], table.concat(stderr, ' ')), + vim.log.levels.ERROR, + { title = 'telescope.nvim' } + ) + return + end + table.insert(success, stashes[idx]) + end + + -- extracted from telescope.utils.notify: + vim.notify(string.format("dropping: 'stash@{%s}' ", table.concat(success, ', ')), vim.log.levels.INFO, { title = 'telescope.nvim' }) +end + +--- Extend the Telescope `git_stash` picker with custom mappings. +function M.git_stash() + builtin.git_stash { + attach_mappings = function(_, map) + actions.select_default:replace(git_apply_stash) + + --- @param prompt_bufnr number: The prompt buffer number from Telescope. + local function git_drop_stash(prompt_bufnr) + -- Try getting all selections in telescope picker + local stashes = M.get_stash_selections(prompt_bufnr) + if stashes == false then + return + end + assert(type(stashes) == 'table', 'Telescope picker selection did not result in list!') + + -- try dropping and close picker when done + M.git_drop_stash(stashes) + actions.close(prompt_bufnr) + end + map({ 'n', 'i' }, '', git_drop_stash) + return true + end, + } +end + +return M diff --git a/lua/kickstart/plugins/conform.lua b/lua/kickstart/plugins/conform.lua index 476b80b..43a42b0 100644 --- a/lua/kickstart/plugins/conform.lua +++ b/lua/kickstart/plugins/conform.lua @@ -19,7 +19,7 @@ return { -- Disable "format_on_save lsp_fallback" for languages that don't -- have a well standardized coding style. You can add additional -- languages here or re-enable it for the disabled ones. - local disable_filetypes = { c = true, cpp = true, php = true } + local disable_filetypes = { c = true, cpp = true, php = true, html = true } local lsp_format_opt if disable_filetypes[vim.bo[bufnr].filetype] then lsp_format_opt = 'never' diff --git a/lua/kickstart/plugins/telescope.lua b/lua/kickstart/plugins/telescope.lua index 7e0eb68..a22099d 100644 --- a/lua/kickstart/plugins/telescope.lua +++ b/lua/kickstart/plugins/telescope.lua @@ -191,6 +191,13 @@ return { cwd = vim.fn.stdpath 'config', } end, { desc = '[S]earch [N]eovim files' }) + + -- Telescope Git Pickers + local utils = require 'custom.utils.telescope' + vim.keymap.set('n', 'gb', builtin.git_branches, { desc = '[G]it [B]ranches' }) + vim.keymap.set('n', 'gc', builtin.git_commits, { desc = '[G]it [C]ommits' }) + vim.keymap.set('n', 'gC', builtin.git_bcommits, { desc = '[G]it Buffer [C]ommits' }) + vim.keymap.set('n', 'gS', utils.git_stash, { desc = '[G]it [S]tash' }) end, }, }