Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/desdic/marlin.nvim
Smooth sailing through buffers of interest in neovim
https://github.com/desdic/marlin.nvim
Last synced: 7 days ago
JSON representation
Smooth sailing through buffers of interest in neovim
- Host: GitHub
- URL: https://github.com/desdic/marlin.nvim
- Owner: desdic
- License: mit
- Created: 2024-02-12T13:30:46.000Z (9 months ago)
- Default Branch: main
- Last Pushed: 2024-06-09T16:40:44.000Z (5 months ago)
- Last Synced: 2024-08-02T06:19:48.290Z (3 months ago)
- Language: Lua
- Homepage:
- Size: 66.4 KB
- Stars: 20
- Watchers: 1
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-neovim - desdic/marlin.nvim - Like harpoon, but with key differences like project path, split support, no UI. (Marks / PHP)
README
# marlin.nvim
##### Smooth sailing between buffers of interestPersistent and extensible jumps across project buffers of interest with ease.
### Setup
Example using the lazy plugin manager
```lua
{
"desdic/marlin.nvim",
opts = {},
config = function(_, opts)
local marlin = require("marlin")
marlin.setup(opts)local keymap = vim.keymap.set
keymap("n", "fa", function() marlin.add() end, { desc = "add file" })
keymap("n", "fd", function() marlin.remove() end, { desc = "remove file" })
keymap("n", "fx", function() marlin.remove_all() end, { desc = "remove all for current project" })
keymap("n", "f]", function() marlin.move_up() end, { desc = "move up" })
keymap("n", "f[", function() marlin.move_down() end, { desc = "move down" })
keymap("n", "fs", function() marlin.sort() end, { desc = "sort" })
keymap("n", "fn", function() marlin.next() end, { desc = "open next index" })
keymap("n", "fp", function() marlin.prev() end, { desc = "open previous index" })
keymap("n", "", function() marlin.toggle() end, { desc = "toggle cur/last open index" })for index = 1,4 do
keymap("n", ""..index, function() marlin.open(index) end, { desc = "goto "..index })
end
end
}
```If you want to restore the 'session' it can be done via autocmd like
```lua
vim.api.nvim_create_autocmd("VimEnter", {
group = vim.api.nvim_create_augroup("restore_marlin", { clear = true }),
callback = function()
-- If nvim has an argument like file(s) we skip the restore
if next(vim.fn.argv()) ~= nil then
return
end
require("marlin").open_all()
end,
nested = true,
})
```### Default configuration
```lua
local default = {
patterns = { ".git", ".svn" }, -- look for root of project
datafile = vim.fn.stdpath("data") .. "/marlin.json", -- location of data file
open_callback = callbacks.change_buffer -- default way to open buffer
sorter = sorter.by_buffer -- sort by bufferid
save_cursor_location = true
suppress = {
missing_root = false -- don't give warning on project root not found
}
}
```### Easy integration with most status lines
Example with [lualine](https://github.com/nvim-lualine/lualine.nvim)
```lua
return {
"nvim-lualine/lualine.nvim",
config = function()
local marlin = require("marlin")local marlin_component = function()
local indexes = marlin.num_indexes()
if indexes == 0 then
return ""
end
local cur_index = marlin.cur_index()return " " .. cur_index .. "/" .. indexes
endrequire("lualine").setup({
...
sections = {
...
lualine_c = { marlin_component },
...
},
})
end
```### Extending behaviour
`marlin.callbacks` has a few options like
- change_buffer (which does what it says, default)
- use_split (if file is already open in a split switch to it)But its possible to change the open_call function to get the behaviour you want. If you want to open new buffers in a vsplit you can
```lua
open_callback = function(bufnr, _)
vim.cmd("vsplit")
vim.api.nvim_set_current_buf(bufnr)
end,
```Or if want to add an options to open_index that switches to the buffer if already open in a split
```lua
open_callback = function(bufnr, opts)
if opts.use_split then
local wins = vim.api.nvim_tabpage_list_wins(0)
for _, win in ipairs(wins) do
local winbufnr = vim.api.nvim_win_get_buf(win)if winbufnr == bufnr then
vim.api.nvim_set_current_win(win)
return
end
end
endvim.api.nvim_set_current_buf(bufnr)
end,
```Sorting also has a few options like
- by_buffer sorts by buffer id (The order they where opened in)
- by_name (Sorts by path+filename)But they can also be change if you want to write your own sorter.
Choice is yours
### But there is no UI
Correct. I'm not planning on creating a UI but if you really want one you can easily create it.
Example using telescope
```lua
local mindex = 0
local generate_finder = function()
mindex = 0
return require("telescope.finders").new_table({
results = require("marlin").get_indexes(),
entry_maker = function(entry)
mindex = mindex + 1
return {
value = entry,
ordinal = mindex .. ":" .. entry.filename,
lnum = entry.row,
col = entry.col + 1,
filename = entry.filename,
display = mindex .. ":" .. entry.filename .. ":" .. entry.row .. ":" .. entry.col,
}
end,
})
endvim.keymap.set("n", "fx", function()
local conf = require("telescope.config").values
local action_state = require("telescope.actions.state")require("telescope.pickers")
.new({}, {
prompt_title = "Marlin",
finder = generate_finder(),
previewer = conf.grep_previewer({}),
sorter = conf.generic_sorter({}),
attach_mappings = function(_, map)
map("i", "", function(bufnr)
local current_picker = action_state.get_current_picker(bufnr)
current_picker:delete_selection(function(selection)
require("marlin").remove(selection.filename)
end)
end)
map("i", "+", function(bufnr)
local current_picker = action_state.get_current_picker(bufnr)
local selection = current_picker:get_selection()
require("marlin").move_up(selection.filename)
current_picker:refresh(generate_finder(), {})
end)
map("i", "-", function(bufnr)
local current_picker = action_state.get_current_picker(bufnr)
local selection = current_picker:get_selection()
require("marlin").move_down(selection.filename)
current_picker:refresh(generate_finder(), {})
end)
return true
end,
})
:find()
end, { desc = "Telescope marlin" })
```### Why yet another ..
When I first saw harpoon I was immediately hooked but I missed a few key features.
- I use splits and wanted to have it jump to the buffer and not replace the current one.
- I wanted persistent jumps per project and not per directory.Like anyone else missing a feature I created a patch but it seems that many other did the same.
### Issues/Feature request
[FAQ](FAQ.md) might have what you are looking, but pull request are also welcome.
### Credits
Credit goes to [ThePrimeagen](https://github.com/ThePrimeagen/harpoon/) for the idea.