From d409de4e5c40f63ca9e0cc09601954864d373502 Mon Sep 17 00:00:00 2001 From: Brad Sherman Date: Wed, 16 Aug 2023 13:09:39 -0500 Subject: [PATCH] Increase Telescope Options - Thanks to @jamestrew - https://github.com/ThePrimeagen/git-worktree.nvim/pull/80 --- README.md | 43 ++++++ lua/telescope/_extensions/git_worktree.lua | 154 +++++++++++++++------ 2 files changed, 152 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index 26b8afe..e3f0518 100644 --- a/README.md +++ b/README.md @@ -128,6 +128,49 @@ Add the following to your vimrc to load the telescope extension require("telescope").load_extension("git_worktree") ``` +### Configuration +Enjoy the customizability of `telescope.nvim` using all your favorite configurations as well as additional options outlined in the example below. + +```lua +require('telescope').setup{ + defaults = { + ... + }, + pickers = { + ... + }, + extensions = { + git_worktree = { + prompt_title = "Super cool prompt title", + theme = "dropdown", + path_display = { "shorten" }, + layout_config = { + width = 70, + height = 20, + }, + + -- determine what worktree items to show, in order and their corresponding width + -- possible items to show are `branch`, `path`, `sha` + items = { + { "branch", 50 }, + { "sha", 20 }, + }, + -- set custom bindings for worktree related actions + mappings = { + ["i"] = { + [""] = require("telescope").extensions.git_worktree.actions.delete_worktree, + [""] = require("telescope").extensions.git_worktree.actions.toggle_forced_deletion, + }, + ["n"] = { + [""] = require("telescope").extensions.git_worktree.actions.delete_worktree, + [""] = require("telescope").extensions.git_worktree.actions.toggle_forced_deletion, + }, + } + } + } +} +``` + ### Switch and Delete a worktrees To bring up the telescope window listing your workspaces run the following diff --git a/lua/telescope/_extensions/git_worktree.lua b/lua/telescope/_extensions/git_worktree.lua index 10b890a..93b5707 100644 --- a/lua/telescope/_extensions/git_worktree.lua +++ b/lua/telescope/_extensions/git_worktree.lua @@ -10,6 +10,8 @@ local git_worktree = require("git-worktree") local force_next_deletion = false +local wt_actions = {} + local get_worktree_path = function(prompt_bufnr) local selection = action_state.get_selected_entry(prompt_bufnr) return selection.path @@ -23,7 +25,7 @@ local switch_worktree = function(prompt_bufnr) end end -local toggle_forced_deletion = function() +wt_actions.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") @@ -66,7 +68,7 @@ local confirm_deletion = function(forcing) return false end -local delete_worktree = function(prompt_bufnr) +wt_actions.delete_worktree = function(prompt_bufnr) if not confirm_deletion() then return end @@ -106,8 +108,58 @@ local create_input_prompt = function(cb) cb(subtree) end -local create_worktree = function(opts) +local pconf = { + mappings = { + ["i"] = { + [""] = wt_actions.delete_worktree, + [""] = wt_actions.toggle_forced_deletion, + }, + ["n"] = { + [""] = wt_actions.delete_worktree, + [""] = wt_actions.toggle_forced_deletion, + }, + }, + attach_mappings = function(_, _) + action_set.select:replace(switch_worktree) + return true + end, +} + +local get_default_opts = function(opts) opts = opts or {} + local defaults = (function() + if pconf.theme then + return require("telescope.themes")["get_" .. pconf.theme](pconf) + end + return vim.deepcopy(pconf) + end)() + + if pconf.mappings then + defaults.attach_mappings = function(prompt_bufnr, map) + if pconf.attach_mappings then + pconf.attach_mappings(prompt_bufnr, map) + end + for mode, tbl in pairs(pconf.mappings) do + for key, action in pairs(tbl) do + map(mode, key, action) + end + end + return true + end + end + + if opts.attach_mappings then + local opts_attach = opts.attach_mappings + opts.attach_mappings = function(prompt_bufnr, map) + defaults.attach_mappings(prompt_bufnr, map) + return opts_attach(prompt_bufnr, map) + end + end + return vim.tbl_deep_extend("force", defaults, opts) +end + +local create_worktree = function(opts) + opts = get_default_opts(opts) opts.attach_mappings = function() actions.select_default:replace(function(prompt_bufnr, _) local selected_entry = action_state.get_selected_entry() @@ -137,14 +189,21 @@ local create_worktree = function(opts) end local telescope_git_worktree = function(opts) - opts = opts or {} + opts = get_default_opts(opts) local output = utils.get_os_command_output({ "git", "worktree", "list" }) local results = {} - local widths = { - path = 0, - sha = 0, - branch = 0, - } + -- local widths = { + -- path = 0, + -- sha = 0, + -- branch = 0, + -- } + + local items = vim.F.if_nil(opts.items, { + { "branch", 0 }, + { "path", 0 }, + { "sha", 0 }, + }) + local displayer_items = {} local parse_line = function(line) local fields = vim.split(string.gsub(line, "%s+", " "), " ") @@ -156,24 +215,27 @@ 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 - -- Some users have found that transform_path raises an error because telescope.state#get_status - -- outputs an empty table. When that happens, we need to use the default value. - -- This seems to happen in distros such as AstroNvim and NvChad - -- - -- Reference: https://github.com/ThePrimeagen/git-worktree.nvim/issues/97 - local transformed_ok, new_path = pcall(utils.transform_path, opts, entry[key]) - - if transformed_ok then - local path_len = strings.strdisplaywidth(new_path or "") - widths[key] = math.max(val, path_len) + for key, item in ipairs(items) do + if not opts.items then + if item[1] == "path" then + -- Some users have found that transform_path raises an error because telescope.state#get_status + -- outputs an empty table. When that happens, we need to use the default value. + -- This seems to happen in distros such as AstroNvim and NvChad + -- + -- Reference: https://github.com/ThePrimeagen/git-worktree.nvim/issues/97 + local transformed_ok, new_path = pcall(utils.transform_path, opts, entry[item[1]]) + + if transformed_ok then + local path_len = strings.strdisplaywidth(new_path or "") + item[2] = math.max(item[2], path_len) + else + item[2] = math.max(item[2], strings.strdisplaywidth(entry[item[1]] or "")) + end else - widths[key] = math.max(val, strings.strdisplaywidth(entry[key] or "")) + item[2] = math.max(item[2], strings.strdisplaywidth(entry[item[1]] or "")) end - else - widths[key] = math.max(val, strings.strdisplaywidth(entry[key] or "")) end + displayer_items[key] = { width = item[2] } end table.insert(results, index, entry) @@ -185,29 +247,34 @@ local telescope_git_worktree = function(opts) end if #results == 0 then + error("No git branches found") return end local displayer = require("telescope.pickers.entry_display").create({ separator = " ", - items = { - { width = widths.branch }, - { width = widths.path }, - { width = widths.sha }, - }, + items = displayer_items, }) local make_display = function(entry) - return displayer({ - { entry.branch, "TelescopeResultsIdentifier" }, - { utils.transform_path(opts, entry.path) }, - { entry.sha }, - }) + local foo = {} + for _, item in ipairs(items) do + if item[1] == "branch" then + table.insert(foo, { entry[item[1]], "TelescopeResultsIdentifier" }) + elseif item[1] == "path" then + table.insert(foo, { utils.transform_path(opts, entry[item[1]]) }) + elseif item[1] == "sha" then + table.insert(foo, { entry[item[1]] }) + else + error("Invalid git-worktree entry item: " .. tostring(item[1])) + end + end + return displayer(foo) end pickers .new(opts or {}, { - prompt_title = "Git Worktrees", + prompt_title = opts.prompt_title or "Git Worktrees", finder = finders.new_table({ results = results, entry_maker = function(entry) @@ -218,24 +285,21 @@ local telescope_git_worktree = function(opts) 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() end +local git_worktree_setup = function(opts) + pconf.mappings = vim.tbl_deep_extend("force", pconf.mappings, require("telescope.config").values.mappings) + pconf = vim.tbl_deep_extend("force", pconf, opts) +end + return require("telescope").register_extension({ + setup = git_worktree_setup, exports = { git_worktree = telescope_git_worktree, git_worktrees = telescope_git_worktree, create_git_worktree = create_worktree, + actions = wt_actions, }, })