feat(nvim): harpoon + telescope multi-select

- Give my gist some love https://gist.github.com/Pegasust/364b123b40dfc36cd113ae9526f83904
pull/20/head
pegasust 2023-09-24 00:48:54 -07:00
parent 33a164ba98
commit eb6142e06f
2 changed files with 101 additions and 4 deletions

View File

@ -1,7 +1,10 @@
{ {
"$schema": "https://raw.githubusercontent.com/sumneko/vscode-lua/master/setting/schema.json", "$schema": "https://raw.githubusercontent.com/sumneko/vscode-lua/master/setting/schema.json",
"Lua.diagnostics.globals": [ "Lua.diagnostics.globals": [
"vim", "vim"
],
"workspace.library": [
], ],
"Lua.workspace.checkThirdParty": false "Lua.workspace.checkThirdParty": false
} }

View File

@ -358,8 +358,93 @@ vim.api.nvim_create_user_command(
-- telescope -- telescope
local fb_actions = require "telescope".extensions.file_browser.actions local fb_actions = require "telescope".extensions.file_browser.actions
local tel_actions = require("telescope.actions") local tel_actions = require("telescope.actions")
local tel_action_state = require("telescope.actions.state")
local tel_actionset = require("telescope.actions.set") local tel_actionset = require("telescope.actions.set")
-- telescope + harpoon mark
local function default_harpoon_mark()
require('harpoon.mark').add_file()
end
local harpoon_keymap = '<leader>m'
local function telescope_multi_selection(prompt_bufnr)
local picker = tel_action_state.get_current_picker(prompt_bufnr)
---@class telescope.make_entry.Entry
---@field value any
---@field valid boolean | nil
---@field ordinal string for filtering and (fuzzy) search-friendly string
---@field display string|function
---@field filename string | nil
---@field bufnr number | nil
---@field lum number | nil
---@field col number | nil
---@class telescope.make_entry.gen_from_file__rv: telescope.make_entry.Entry
---@field cwd string | nil
---@field path string via __index
---@field __index function
---@type telescope.make_entry.gen_from_file__rv[]
local rv = picker:get_multi_selection()
return rv
end
local function mark_telescope_selections(prompt_bufnr)
-- NOTE: This works for both bulitin Telescope file browser and fuzzy search
local selections = telescope_multi_selection(prompt_bufnr)
--[[
local entries = {}
for k, e in ipairs(selections) do
table.insert(entries, { k = k, e = e })
end
print(vim.inspect({
prompt_bufnr = prompt_bufnr,
selections = selections,
entries = entries,
}))
stdout> (builtin.__file)
{
entries = { { "native_configs/ssh/authorized_keys",
index = 6,
<metatable> = <1>{
__index = <function 1>,
cwd = "/Users/hungtran/local_repos/dotfiles",
display = <function 2>
}
}, { "native_configs/ssh/config", index = 7, <metatable> = <table 1> } },
prompt_bufnr = 56
}
--]]
---@type string[]
local filenames = {}
for _, entry in ipairs(selections) do
local has_path, path = pcall(function() return entry:__index("path") --[[ @as string ]] end)
if has_path then
table.insert(filenames, path)
goto continue
end
-- invariant: pcall on has_path false will assign second rv as the error
-- payload. Most of the time, this is a string, but for safety, we could
-- not assume so.
local err = path
log.warn("No `.path` for entry `" .. vim.inspect(entry) .. "`: " .. vim.inspect(err))
::continue::
end
log.debug(vim.inspect(filenames))
for _, filename in pairs(filenames) do
require('harpoon.mark').add_file(filename)
end
end
local function term_height() local function term_height()
return vim.opt.lines:get() return vim.opt.lines:get()
end end
@ -370,13 +455,15 @@ require('telescope').setup {
n = { n = {
['<C-u>'] = function(prompt_bufnr) tel_actionset.shift_selection(prompt_bufnr, -math.floor(term_height() / 2)) end, ['<C-u>'] = function(prompt_bufnr) tel_actionset.shift_selection(prompt_bufnr, -math.floor(term_height() / 2)) end,
['<C-d>'] = function(prompt_bufnr) tel_actionset.shift_selection(prompt_bufnr, math.floor(term_height() / 2)) end, ['<C-d>'] = function(prompt_bufnr) tel_actionset.shift_selection(prompt_bufnr, math.floor(term_height() / 2)) end,
[harpoon_keymap] = function(prompt_bufnr)
mark_telescope_selections(prompt_bufnr)
end,
}, },
}, },
}, },
extensions = { extensions = {
live_grep_args = { live_grep_args = {
auto_quoting = true, auto_quoting = true,
mappings = {},
}, },
fzf = { fzf = {
fuzzy = true, -- allow fuzzy matches fuzzy = true, -- allow fuzzy matches
@ -435,12 +522,14 @@ remap('n', '<leader>fa', function()
end, { desc = '[F]ind [A]ll files' }) end, { desc = '[F]ind [A]ll files' })
remap('n', '<leader>fg', function() remap('n', '<leader>fg', function()
require('telescope.builtin').live_grep() require('telescope').extensions.live_grep_args.live_grep_args()
end, { desc = '[F]ind thru [G]rep' }) end, { desc = '[F]ind thru [G]rep' })
remap('n', '<leader>fug', function() remap('n', '<leader>fug', function()
-- This relies on many factors: We use `rg` and that `-g '**/*'` effectively -- This relies on many factors: We use `rg` and that `-g '**/*'` effectively
-- drops ignore rules like the default `.gitignore` rule. -- drops ignore rules like the default `.gitignore` rule.
vim.notify("fuzzy unrestricted grep is deprecated, use Find thru Grep with `-uuu` query instead")
require('telescope.builtin').live_grep({ glob_pattern = '**/*' }) require('telescope.builtin').live_grep({ glob_pattern = '**/*' })
end, { desc = '[F]ind thru [u]nrestricted [G]rep' }) end, { desc = '[F]ind thru [u]nrestricted [G]rep' })
@ -566,7 +655,12 @@ require('guess-indent').setup {
} }
-- harpoon: O(1) buffer/terminal switching -- harpoon: O(1) buffer/terminal switching
remap('n', '<leader>m', function() require('harpoon.mark').add_file() end, { desc = "[H]arpoon [M]ark" }) remap('n', harpoon_keymap, function()
local is_err, err = pcall(require('harpoon.mark').add_file)
if is_err then
log.warn(vim.inspect(err))
end
end, { desc = "[H]arpoon [M]ark" })
local function harpoon_nav(key, nav_file_index, lead_keybind) local function harpoon_nav(key, nav_file_index, lead_keybind)
lead_keybind = lead_keybind or '<leader>h' lead_keybind = lead_keybind or '<leader>h'
assert(type(key) == "string", "expect key to be string(keybind)") assert(type(key) == "string", "expect key to be string(keybind)")