Since the Harpoon project is very conservative on new features, I tried to implement a few nice-to-haves using the plugin API of Harpoon.
This feature is experimental, this is why it's disabled by default. The option registers an autocommand on DirChanged, but you can also always call harpoonEx:reset() manually when you want to trigger a reload, with or without setting the option.
To enable, add the following option to the plugin like so:
"theprimeagen/harpoon",
branch = "harpoon2",
dependencies = {
{"mike-jl/harpoonEx", opts = { reload_on_dir_change = true} },
},
You might say "this already exists in the current plugin", and you are right, but the plugin sometimes loses count of the currently selected item (e.g. when you switch buffer with some other means then Harpoon). So I'm keeping my own count and (in my tests at least) the function always works as expected.
Add the following to your Harpoon plugin config:
-- Include harpoonEx as a dependency
"theprimeagen/harpoon",
branch = "harpoon2",
dependencies = {
"mike-jl/harpoonEx",
},
config = function()
local harpoonEx = require("harpoonEx")
-- load extension
harpoon:extend(harpoonEx.extend())
-- register keys
-- Toggle previous & next buffers stored within Harpoon list
vim.keymap.set("n", "<S-Tab>", function()
harpoonEx.next_harpoon(harpoon:list(), true)
end, { desc = "Switch to previous buffer in Harpoon List" })
vim.keymap.set("n", "<Tab>", function()
harpoonEx.next_harpoon(harpoon:list(), false)
end, { desc = "Switch to next buffer in Harpoon List" })
-- the rest of your config function
end
This function also already exists in the plugin, but again, there are some caviats with the current implementation. With the delete method form harpoonEx, the item is not just set to nil, but removed from the list entirely. This prevents data loss on quitting nvim, because currently all items after a blank line are discarded. (see #573) The delete method takes three arguments, fhe first one, the list, is required. The socond one the index to delete and the third one is an option if the next harpoon item should be selected after the deletion.
Add the following to your Harpoon plugin config:
-- Include harpoonEx as a dependency
"theprimeagen/harpoon",
branch = "harpoon2",
dependencies = {
"mike-jl/harpoonEx",
},
config = function()
local harpoonEx = require("harpoonEx")
-- load extension
harpoon:extend(harpoonEx.extend())
-- register key
vim.keymap.set("n", "<M-d>", function()
harpoonEx.delete(harpoon:list())
end, { desc = "Add current filte to Harpoon List" })
-- the rest of your config function
end
- <M-d> = Delete selected Item
- <M-p> = Move selected Item up
- <M-n> = Move selected Item down
Add the following to your Harpoon plugin config:
-- Include harpoonEx and telescope as a dependency
"theprimeagen/harpoon",
branch = "harpoon2",
dependencies = {
"nvim-telescope/telescope.nvim",
"mike-jl/harpoonEx",
},
config = function()
local harpoonEx = require("harpoonEx")
vim.keymap.set("n", "<M-e>", function()
require("telescope").extensions.harpoonEx.harpoonEx({
-- Optional: modify mappings, default mappings:
attach_mappings = function(_, map)
local actions = require("telescope").extensions.harpoonEx.actions
map({ "i", "n" }, "<M-d>", actions.delete_mark)
map({ "i", "n" }, "<M-k>", actions.move_mark_up)
map({ "i", "n" }, "<M-j>", actions.move_mark_down)
return true
end,
})
return true
end, { desc = "Open harpoon window" })
-- the rest of your config function
end
Additional Info: There are a few additional ways to configure a telescope plugin. You can also configure it in the telescope setup (call to load_extension required), or use mappings instead of attach_mappings This way is just the easiest for me to show in the readme. Details see telescope documentation.
Add the following to your Harpoon plugin config:
-- Include harpoonEx and telescope as a dependency
"theprimeagen/harpoon",
branch = "harpoon2",
dependencies = {
"nvim-telescope/telescope.nvim",
"mike-jl/harpoonEx",
},
config = function()
local harpoonEx = require("harpoonEx")
vim.keymap.set("n", "<leader>sh", function()
harpoonEx.telescope_live_grep(harpoon:list())
end, { desc = "Live grep harpoon files" })
-- the rest of your config function
end
The currently open buffer will always be shown, even if it's not on the Harpoon List. You can also navigate by using the mouse, were a left click navigates to the item and a right click adds or removes the item form the harpoon list.
Example for tabline, but can be used anywhere of course. Add the following to your lualine plugin config:
"nvim-lualine/lualine.nvim",
-- Include harpoonEx and harpoon as a dependency
dependencies = {
"theprimeagen/harpoon",
"mike-jl/harpoonEx",
},
opts = {
tabline = {
lualine_a = {
{
"harpoons",
-- default config
show_filename_only = true, -- Shows shortened relative path when set to false.
hide_filename_extension = false, -- Hide filename extension when set to true.
show_modified_status = true, -- Shows indicator when the buffer is modified.
mode = 0, -- 0: Shows harpoon file name
-- 1: Shows harpoon index
-- 2: Shows harpoon file name + harpoon index
max_length = vim.o.columns * 2 / 3, -- Maximum width of harpoons component,
-- it can also be a function that returns
-- the value of `max_length` dynamically.
filetype_names = {
TelescopePrompt = 'Telescope',
dashboard = 'Dashboard',
packer = 'Packer',
fzf = 'FZF',
alpha = 'Alpha',
harpoon = "Harpoon"
}, -- Shows specific buffer name for that filetype ( { `filetype` = `buffer_name`, ... } )
-- Automatically updates active buffer color to match color of other components (will be overridden if harpoons_colors is set)
use_mode_colors = false,
harpoons_color = {
-- Same values as the general color option can be used here.
active = 'lualine_{section}_normal', -- Color for active buffer.
inactive = 'lualine_{section}_inactive', -- Color for inactive buffer.
},
symbols = {
modified = ' ●', -- Text to show when the buffer is modified
alternate_file = '#', -- Text to show to identify the alternate file
directory = '', -- Text to show when the buffer is a directory
},
}
}
}
}
Add the following to your Harpoon plugin config:
init = function()
local harpoon = require("harpoon")
local harpoonEx = require("harpoonEx")
-- check if nvim was started with no arguments or just a dir as argument
-- if so, try to select the first item in the harpoon list
if
(vim.fn.argc() == 0 or (vim.fn.argc() == 1 and vim.fn.isdirectory(vim.fn.argv(0)) == 1))
and vim.api.nvim_get_option_value("buftype", { buf = 0 }) == ""
then
vim.schedule(function()
harpoonEx.next_harpoon(harpoon:list(), false)
end)
end
end,
Special thanks goes out to ThePrimagen, for creating the awesome Harpoon plugin and to kimabrandt-flx for coming up with the code to keep track of the index of the active item.