Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Ability to switch between loaded scopes #133

Open
dpetka2001 opened this issue Mar 18, 2024 · 7 comments
Open

feat: Ability to switch between loaded scopes #133

dpetka2001 opened this issue Mar 18, 2024 · 7 comments

Comments

@dpetka2001
Copy link

I know you can currently can do something like Grapple cycle forward scope=name_of_scope, but it would be really nice if some kind of API would be made available to the user to cycle through the loaded scopes. Maybe something like Grapple cycle_loaded next/previous. This way I can just set specific keymaps that cycle through my loaded scopes instead of having to specify the scope that I want to cycle through.

@cbochs
Copy link
Owner

cbochs commented Mar 20, 2024

I like this suggestion. One clarification, there are two UIs for scopes: one for the scopes and one for the loaded scopes. Were you referring to one in particular?

Scopes
image

Loaded Scopes
image

@dpetka2001
Copy link
Author

dpetka2001 commented Mar 20, 2024

I was referring to the second picture of Loaded Scopes, as like I understand it is the scopes that user has enabled by using the corresponding scopes from the first picture.

So, for example, if I open the first picture, I'm able to enable 2 scopes for a buffer by pressing <S-CR> on 2 different scopes (let's say cwd and git_branch). Then, in the loaded scopes window it will show these 2 scopes enabled by the user. What I was thinking is that instead of opening the loading scopes window, I could specify keymaps to cycle through next/prev loaded scope and have directly access to the tags of the currently used scope. That would also show in the lualine component of the plugin hopefully.

So just an API like cycle_loaded next/prev (or forward/backward like it already is when you do grapple cycle forward scope=name_of_scope). Because right now you have to specify the scope you want to cycle to. But in the loaded scopes you could maybe just do cycle_loaded forward/backward without specifying a scope. It would just cycle through the next/prev loaded scope of the ones that are present in the loaded scopes window.

@cbochs
Copy link
Owner

cbochs commented Mar 21, 2024

So, for example, if I open the first picture, I'm able to enable 2 scopes for a buffer by pressing <S-CR> on 2 different scopes (let's say cwd and git_branch)

It might be good to clarify a couple things here.

The action <S-CR> is not necessarily "enabling", but instead changing the default scope used (the one set during Grapple.setup). There can only be one default scope in use at some point in time.

The Loaded Scopes window primarily shows information on which "tag containers" have been loaded. These "tag containers" have an ID (usually a pseudo file path), which is determined when a scope is "resolved".

For example, let's say you're in ~/git/grapple.nvim. The following scopes can resolve to something like:

  • Scope: git_branch > Resolved ID: ~/git/grapple.nvim:branch1 (git checkout branch1)
  • Scope: git_branch > Resolved ID: ~/git/grapple.nvim:branch2 (git checkout branch2)
  • Scope: git > Resolved ID: ~/git/grapple.nvim
  • Scope: cwd > Resolved ID ~/git/grapple.nvim
  • Scope: global > Resolved ID global

So, if you have selected or opened any tags for the git and global scopes then the Loaded Scopes window will show:

image

Now, if you select or open the cwd scope, since it resolved to the same ID your Loaded Scopes will not change since both git and cwd resolve to the same ID.

(or forward/backward like it already is when you do grapple cycle forward scope=name_of_scope).

To be honest, I'm beginning to warm up to the verbiage next and prev{ious}. I might think about soft-deprecating (forward, backward) for (next, prev).

Because right now you have to specify the scope you want to cycle to. But in the loaded scopes you could maybe just do cycle_loaded forward/backward without specifying a scope. It would just cycle through the next/prev loaded scope of the ones that are present in the loaded scopes window.

I like the idea of something like this:

---@param type "tags" | "scopes" | "loaded"
---@param direction "next" | "prev"
---@param opts? grapple.options | { name: string } | { id: string }
function Grapple.cycle(type, direction, opts)
    ...
end

With user command:

Grapple cycle {type} {direction} [opts...]

Where opts allows the user to specify a "starting point" (e.g. { index = 1 } for tags, { name = "git" } for scopes, { id = "global" } for loaded). This would of course be a breaking change, but might be worth the refactor.

@dpetka2001
Copy link
Author

dpetka2001 commented Mar 21, 2024

Now, if you select or open the cwd scope, since it resolved to the same ID your Loaded Scopes will not change since both git and cwd resolve to the same ID.

Thank you for this clarification. I wasn't aware of this, but just tried it and observed the behavior you're describing. Now I understand better the resolution of ID that happens behind the scenes. With that in mind, I believe it would be good if you documented the example you provided in your previous post about the resolution of IDs. That way it falls to the user to make sure to differentiate between different IDs in the loaded scopes window.

I really don't know what the best way to do it would be. I just saw that you enabled in loaded scopes window to show with <S-CR> only loaded scopes or even unloaded scopes. That means you keep some kind of state for the loaded scopes?

The purpose of the initial post (and after you clarified about how ID resolution happens) is something like the following workflow to be achieved (if possible of course, you're the one who maintains the code and I won't be expecting all users' requested features to be catered to):
Let's say that the user is fully aware of the ID resolution that happens about how the loaded scopes window shows the loaded scopes. So, let's say the user has changed the default scope to the cwd scope and the global one with the different tags between the 2. So in the loaded scopes, you will see the ID of the resolved cwd scope and the global scope. Maybe the user will add another git branch scope in the future and it will also show in the loaded scopes window. I would like to assign 2 keymaps. 1 to go the next loaded scope and 1 to go the previous loaded scope from the IDs that are present in the loaded scopes window.

@cbochs
Copy link
Owner

cbochs commented Mar 21, 2024

With that in mind, I believe it would be good if you documented the example you provided in your previous post about the resolution of IDs.

Will make sure to update!

That means you keep some kind of state for the loaded scopes?

Yup. And if you're curious it's right here 🙂

I would like to assign 2 keymaps. 1 to go the next loaded scope and 1 to go the previous loaded scope from the IDs that are present in the loaded scopes window.

I've made a few improvements recently to managing save files and the Loaded Scopes window (see: new keymaps in Loaded Scopes window and Grapple.prune). I think Grapple is in a good place to implement something along the lines of:

---@param type "tags" | "scopes" | "loaded"
---@param direction "next" | "prev"
---@param opts? grapple.options | { name: string } | { id: string }
function Grapple.cycle(type, direction, opts)
    ...
end

Then you could add your keybinds like:

vim.keymap.set("n", "", "<cmd>Grapple cycle loaded next<cr>")
vim.keymap.set("n", "", "<cmd>Grapple cycle loaded prev<cr>")

@dpetka2001
Copy link
Author

Thank you very much for taking time to implement this. I look forward to its completion.

@cbochs
Copy link
Owner

cbochs commented Apr 27, 2024

@dpetka2001 With 6c88bfd, Grapple now supports cycling through scopes. While you cannot cycle through scope IDs quite yet, you can accomplish the above workflow by hiding the scopes you do not use. For example,

Hide all scopes but global, git, and git_branch (see: grapple.scope_definition.shown:

require("grapple").setup({
    default_scopes = {
        git = { shown = true },
        git_branch = { shown = true },
        global = { shown = true },
    }

})

Cycle through the above three scopes with

require("grapple").cycle_scopes("next")
require("grapple").cycle_scopes("prev")

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants