diff --git a/lua/telescope/_extensions/git_worktree.lua b/lua/telescope/_extensions/git_worktree.lua index 706cd2b..7d8ff27 100644 --- a/lua/telescope/_extensions/git_worktree.lua +++ b/lua/telescope/_extensions/git_worktree.lua @@ -1,5 +1,3 @@ -local Path = require("plenary.path") -local Window = require("plenary.window.float") local strings = require("plenary.strings") local pickers = require("telescope.pickers") local finders = require("telescope.finders") @@ -12,11 +10,17 @@ local git_worktree = require("git-worktree") local force_next_deletion = false +-- Get the path of the selected worktree +-- @param prompt_bufnr number: the prompt buffer number +-- @return string: the path of the selected worktree local get_worktree_path = function(prompt_bufnr) local selection = action_state.get_selected_entry(prompt_bufnr) return selection.path end +-- Switch to the selected worktree +-- @param prompt_bufnr number: the prompt buffer number +-- @return nil local switch_worktree = function(prompt_bufnr) local worktree_path = get_worktree_path(prompt_bufnr) actions.close(prompt_bufnr) @@ -25,26 +29,35 @@ local switch_worktree = function(prompt_bufnr) end end +-- Toggle the forced deletion of the next worktree +-- @return nil local toggle_forced_deletion = function() -- redraw otherwise the message is not displayed when in insert mode if force_next_deletion then - print('The next deletion will not be forced') - vim.fn.execute('redraw') + vim.print("The next deletion will not be forced") + vim.fn.execute("redraw") else - print('The next deletion will be forced') - vim.fn.execute('redraw') + vim.print("The next deletion will be forced") + vim.fn.execute("redraw") force_next_deletion = true end end +-- Handler for successful deletion +-- @return nil local delete_success_handler = function() force_next_deletion = false end +-- Handler for failed deletion +-- @return nil local delete_failure_handler = function() print("Deletion failed, use to force the next deletion") end +-- Ask the user to confirm the deletion of a worktree +-- @param forcing boolean: whether the deletion is forced +-- @return boolean: whether the deletion is confirmed local ask_to_confirm_deletion = function(forcing) if forcing then return vim.fn.input("Force deletion of worktree? [y/n]: ") @@ -53,6 +66,9 @@ local ask_to_confirm_deletion = function(forcing) return vim.fn.input("Delete worktree? [y/n]: ") end +-- Confirm the deletion of a worktree +-- @param forcing boolean: whether the deletion is forced +-- @return boolean: whether the deletion is confirmed local confirm_deletion = function(forcing) if not git_worktree._config.confirm_telescope_deletions then return true @@ -68,6 +84,9 @@ local confirm_deletion = function(forcing) return false end +-- Delete the selected worktree +-- @param prompt_bufnr number: the prompt buffer number +-- @return nil local delete_worktree = function(prompt_bufnr) if not confirm_deletion() then return @@ -76,79 +95,63 @@ local delete_worktree = function(prompt_bufnr) local worktree_path = get_worktree_path(prompt_bufnr) actions.close(prompt_bufnr) if worktree_path ~= nil then - git_worktree.delete_worktree(worktree_path, force_next_deletion, { - on_failure = delete_failure_handler, - on_success = delete_success_handler - }) + git_worktree.delete_worktree(worktree_path, force_next_deletion, { + on_failure = delete_failure_handler, + on_success = delete_success_handler, + }) end end +-- Create a prompt to get the path of the new worktree +-- @param cb function: the callback to call with the path +-- @return nil local create_input_prompt = function(cb) - - --[[ - local window = Window.centered({ - width = 30, - height = 1 - }) - vim.api.nvim_buf_set_option(window.bufnr, "buftype", "prompt") - vim.fn.prompt_setprompt(window.bufnr, "Worktree Location: ") - vim.fn.prompt_setcallback(window.bufnr, function(text) - vim.api.nvim_win_close(window.win_id, true) - vim.api.nvim_buf_delete(window.bufnr, {force = true}) - cb(text) - end) - - vim.api.nvim_set_current_win(window.win_id) - vim.fn.schedule(function() - vim.nvim_command("startinsert") - end) - --]] - -- - local subtree = vim.fn.input("Path to subtree > ") cb(subtree) end +-- Create a worktree +-- @param opts table: the options for the telescope picker (optional) +-- @return nil local create_worktree = function(opts) opts = opts or {} opts.attach_mappings = function() - actions.select_default:replace( - function(prompt_bufnr, _) - local selected_entry = action_state.get_selected_entry() - local current_line = action_state.get_current_line() + actions.select_default:replace(function(prompt_bufnr, _) + local selected_entry = action_state.get_selected_entry() + local current_line = action_state.get_current_line() - actions.close(prompt_bufnr) + actions.close(prompt_bufnr) - local branch = selected_entry ~= nil and - selected_entry.value or current_line + local branch = selected_entry ~= nil and selected_entry.value or current_line - if branch == nil then - return - end + if branch == nil then + return + end - create_input_prompt(function(name) - if name == "" then - name = branch - end - git_worktree.create_worktree(name, branch) - end) + create_input_prompt(function(name) + if name == "" then + name = branch + end + git_worktree.create_worktree(name, branch) end) - - -- do we need to replace other default maps? + end) return true end require("telescope.builtin").git_branches(opts) end +-- List the git worktrees +-- @param opts table: the options for the telescope picker (optional) +-- @return nil local telescope_git_worktree = function(opts) opts = opts or {} - local output = utils.get_os_command_output({"git", "worktree", "list"}) + local output = utils.get_os_command_output({ "git", "worktree", "list" }) local results = {} local widths = { path = 0, sha = 0, - branch = 0 + branch = 0, } local parse_line = function(line) @@ -162,9 +165,8 @@ local telescope_git_worktree = function(opts) if entry.sha ~= "(bare)" then local index = #results + 1 for key, val in pairs(widths) do - if key == 'path' then - local new_path = utils.transform_path(opts, entry[key]) - local path_len = strings.strdisplaywidth(new_path or "") + if key == "path" then + local path_len = strings.strdisplaywidth(entry[key] or "") widths[key] = math.max(val, path_len) else widths[key] = math.max(val, strings.strdisplaywidth(entry[key] or "")) @@ -183,53 +185,55 @@ local telescope_git_worktree = function(opts) return end - local displayer = require("telescope.pickers.entry_display").create { + local displayer = require("telescope.pickers.entry_display").create({ separator = " ", items = { { width = widths.branch }, { width = widths.path }, { width = widths.sha }, }, - } + }) local make_display = function(entry) - return displayer { + return displayer({ { entry.branch, "TelescopeResultsIdentifier" }, { utils.transform_path(opts, entry.path) }, { entry.sha }, - } + }) end - pickers.new(opts or {}, { - prompt_title = "Git Worktrees", - finder = finders.new_table { - results = results, - entry_maker = function(entry) - entry.value = entry.branch - entry.ordinal = entry.branch - entry.display = make_display - return entry + pickers + .new(opts or {}, { + prompt_title = "Git Worktrees", + finder = finders.new_table({ + results = results, + entry_maker = function(entry) + entry.value = entry.branch + entry.ordinal = entry.branch + entry.display = make_display + return entry + end, + }), + sorter = conf.generic_sorter(opts), + attach_mappings = function(_, map) + action_set.select:replace(switch_worktree) + + map("i", "", delete_worktree) + map("n", "", delete_worktree) + map("i", "", toggle_forced_deletion) + map("n", "", toggle_forced_deletion) + + return true end, - }, - sorter = conf.generic_sorter(opts), - attach_mappings = function(_, map) - action_set.select:replace(switch_worktree) - - map("i", "", delete_worktree) - map("n", "", delete_worktree) - map("i", "", toggle_forced_deletion) - map("n", "", toggle_forced_deletion) - - return true - end - }):find() + }) + :find() end -return require("telescope").register_extension( - { - exports = { - git_worktree = telescope_git_worktree, - git_worktrees = telescope_git_worktree, - create_git_worktree = create_worktree - } - }) +-- Register the extension +-- @return table: the extension +return require("telescope").register_extension({ + exports = { + git_worktrees = telescope_git_worktree, + create_git_worktree = create_worktree, + }, +})