GnikDroy / projections.nvim

A map to your filesystem
GNU General Public License v3.0
233 stars 8 forks source link

[feat] tab scoped sessions #40

Open ibrokemypie opened 1 year ago

ibrokemypie commented 1 year ago

Is your feature request related to a problem? Please describe. I often use tabs for working on different projects within the same nvim instance, eg. frontend in one tab and backend in another, but with projections.nvim if I open a second tab and then open a project within that, the first tab and project gets lost. (My session options have localoptions appended and tabpages + buffers removed)

Describe the solution you'd like A way to restrict session management to per tab, or even better, a way to restrict session management to per project (tab 1 and 2 are within project a, so they are managed by project a's session, while tab 3 is in project b, so it is managed by project b's session)

If appropriate, have you considered any alternatives? Have looked at recession which is a replacement for the inbuilt nvim session management commands with support for per tab sessions, but getting that to work with projects the same way projections does is a bit daunting, and I think its a far request to be able to do this within projections (maybe using recession under the hood)

Additional context Add any other context or screenshots about the feature request here.

GnikDroy commented 1 year ago

A way to restrict session management to per tab

Possible. Neovim's :mksession supports this, so I will make this available to projections as well. A lot of the groundwork is already present in projections.

A way to restrict session management to per project

Maybe possible. There is no way to specify which tabpages to store in the call for :mksession. So, natively, neovim doesn't support this. It is maybe possible with the help of multiple tab scoped session files. But things do get complicated.

request to be able to do this within projections (maybe using recession under the hood)

The plugin looks great. But projections won't support using recession under the hood. Projections is a thin wrapper around :mksession, as such, will only support things neovim's :mksession supports.

That being said, you can always hack with this code. The codebase is tiny, and documented well enough. The project part is completely decoupled from sessions as well.

You would need to take a look at these files:

GnikDroy commented 1 year ago

I have given this some thought. There are some inherent problems with this. Additionally, I think I have a workflow that you would like.

Problem

1) Buffers aren't associated with tabs. There is no concept of a tab-scoped buffer. So, :mksession will either store all hidden/unloaded buffers or none. Therefore, removal of tabpages must be accompanied by removal of buffers.

2) When opening a new "project" in a tab, I must close the existing stuff. i.e Close all windows belonging to the tabpage (possible) and close all hidden/unloaded buffers in the tabpage (not possible, because once again, buffers don't belong to tabs)

In general, neovim tabs aren't supposed to be used like this. A lot of issues surface when I try to implement this. (What happens if the same buffer is open in both tabs?)

Solution

But I think all this is unnecessary. The solution to your problem is pretty simple. Firstly, enable tabpages in sessionoptions. Suppose, you have two "projects": frontend and backend.

Case 1

frontend and backend are in a main project directory.

─── workspace
    ├── web_project
    │    ├── frontend
    │    └── backend
    └── unrelated

Now web_project is a project. frontend and backend are pseudo-projects.

For your, workflow: Open one tabpage for each. :tcd into frontend in first tab, and :tcd into backend from second. Now, you have your desired workflow. You can work as normal. projections will save the entire session.

Case 2

frontend and backend are in a workspace with multiple projects

─── workspace
    ├── web_frontend
    ├── web_backend
    └── unrelated

Solution: Just restructure your directories to that of case 1.

Case 3

You want genuinely different "projects" in different tabs. That is frontend in tab 1 and unrelated in tab 2.

Solution: ???

First question you need to ask yourself: Is the difference between tabs vs sessions relevant in this case?

You can't see tab 1 and tab 2 at the same time, just like you can't see projects at the same time. Switching tabs behaves exactly the same as switching projects, no?

So, why is the tab based approach superior to project based one, in this case? Especially, since the projects are "unrelated". You can't share stuff like :pwd across the projects. So, the problem might be self-inflicted?

GnikDroy commented 1 year ago

That being said. I have actually implemented this in a local branch. It was relatively simple change requiring only to change switcher.lua.

If you would like to try it out for yourself, then I will push the branch. Since this feature doesn't really change anything for existing users, I can add it to projections. (You will need to disable both tabpages and buffers)

But, I would like you to consider the above first.

ibrokemypie commented 1 year ago

Wow thank you for putting all this time and thought into it! Didn't expect so much! I think what I left out/should have been more specific about is that yes sometimes I would be working on two different but related projects, in which case it makes sense to store both tabs as one session/project, I am usually opening a new tab when working on a project to quickly work on a completely different unrelated project, eg. a tab open for a backend project, and then a second tab open for my nvim config, or another service's backend. This isn't really different from just switching projects entirely I guess, its more of just a workflow/reduction of context switch thing, its easier to me and displaces less working memory to press a hot key to instantly switch between two projects, and the same again to switch back, than to open a project picker, find the other project and then have the entire editor kind of reloaded for the new project, and have to do the reverse to get back. Maybe I could write a 'tabline' that can have projects pushed into it or popped out of it, and then have the same bind to switch between them as an emulation of the project-tabs behaviour I want?

Definitely not a necessity, but it would be really nice for my workflow/what I am used to. I guess an alternative is just having two different terminals with nvim open and configured in a tabbed layout with my window manager, but that adds the additional mental load of having to remember to use wm layer bindings for a context that is my mind is my editor. Would love to give your branch a whirl!

GnikDroy commented 1 year ago

What if projections stores a stack of visited projects. And makes something like :ProjectionsNext and :ProjectionsPrevious available?

My current implementation of tab local projects has a severe limitation of not being able to associate multiple tabs with a project. Implementing that is a bit complicated.

ibrokemypie commented 1 year ago

Hmm I think that might be a good compromise! As long as there's a nice interface for getting the list of open projects, and for closing an open project, I think I would be able to make that work for my needs, with the added bonus as you say of keeping tabs working as tabs too!