Implementing auto back and forth in grapple.nvim
So I have a workspace-like workflow in neovim where I tag certain files and I switched to those files using certain shortcuts. Basically what primeagen does with harpoon but I use grapple.nvim instead.
I switched to grapple.nvim from harpoon for a variety of reasons:
- The cursor position is actually saved after quitting1.
- It has different **scopes**. Meaning you can make it so that the list of tagged files changes as per cwd, git branch, initial directory etc.
- Has a clean and extensive API(we'd discuss that later.)
I was very happy and efficient with my workflow and this whole file tagging thing but there was one issue.
Suppose I'm on tag 1, I want to have just a quick peek at 3, maybe I forgot how I defined a certain function or variable or what I called it, so I press <leader>3 to go to tag 3, all good and well, and finally I press <leader>1 to go back to tag 1.
This works really well no problem whatsoever but I still wish switching to tagged files had an auto-back-and-forth mechanism like from i3wm.
In case you don't know what that is it basically allows you to switch to the last tag upon hitting the keybinding for the current tag:
- Be on tag 1
- Press
<leader>3 - On tag 3 now
- Press
<leader>3 - Back to tag 1 again
Grapple.nvim does not support such feature out of the box. So I thought no biggie I'll just modify the source code a bit adding an optional auto back and forth feature and create a pr at last. But as it turns out the source code for grapple.nvim is massive and I'm not familiar with neovim's API enough to do it on my own.
Thankfully though grapple.nvim has a very extensive and clean API which makes our job much easier.
My bindings before the change:
,
And here they are now:
local
local keys =
-- Static keys
table.
table.
for i = 1, 9
return
I'm basically checking whether the current buffer/file is tagged using require("grapple").exists() and if so I move onto the next condition, which is whether the file at tag x is equal to the current file(the zeroth buffer), using require("grapple").find({ index = x }) == require("grapple").find({ buffer = 0 }), and if that too is true I move to the last buffer with vim.cmd("b#")
If neither of those conditions succeed I simply move onto the desired tag.
Here's how it looks like in action: