GnikDroy / projections.nvim

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

[Feature request] "In project: x" capability #27

Open Gazareth opened 1 year ago

Gazareth commented 1 year ago

Is your feature request related to a problem? Please describe. I'd like to display which project I'm currently in on my statusbar. I think the closest we'd have is to use the session load hooks, but I'm not sure we'd know which project we've just loaded into? And it also wouldn't tell us when we load up a project for the first time.

Describe the solution you'd like I was thinking a global could be set, i.e. `vim.g.GnikDroy_projections.project = "MyProjectFolderName" each time the switcher is used or a sesion is loaded.

If appropriate, have you considered any alternatives? We could provide hooks on the switcher as well, for people to pass in callbacks with receive the project name as an argument.

GnikDroy commented 1 year ago

@Gazareth The wiki has something similar. https://github.com/GnikDroy/projections.nvim/wiki#writing-a-status-line-component-for-projections

Let me know if this is all you want.

Gazareth commented 1 year ago

Ah excellent, thank you. This should do what I need for now.

I do still think it might be worth having a more explicit indicator that we are in a project though. If you could visit a project's directory without 'officially' being in a project, you could edit one or two files and avoid overwriting your session, which you might have wanted to return to later, or even immediately afterwards by using the project browser.

GnikDroy commented 1 year ago

But how do I make, "inside a project", more explicit? I can't think of any setting I can tweak in the default projections config. Apart from writing a status line component, how do you want projections to indicate projects?

Overwriting sessions is definitely annoying. Any ideas to make this happen less frequently are welcome. But, since the user sets up all the autocmds, can't think of anything else projections can do.

Gazareth commented 1 year ago

I was thinking projections could keep track internally when the switcher or session loader is used to load into a project. It could set a variable to the directory of the project you're loading into.

Then, users could call something like:

require('projections.session').current_project()

To return that path.

Looking at the code it seems all the classes are implemented in a static way, which is nice, and I'm hesitant to pollute that with some kind of global state persistence, so if you have any guidance on where the variable could live and where it would be set, I'd be happy to open a PR for this.

GnikDroy commented 1 year ago

could keep track internally when the switcher or session loader is used to load into a project

I don't see a strong reason to track this internally. Since it shouldn't be very hard to track this yourself.

You can maybe look into a post restore hook that saves the restored project's directory in a global variable.

require("projections").setup({
    restore_hooks = { 
        post = function
            LAST_PROJECT_DIR = vim.loop.cwd()
        end,
    },
})

You can then use Session.info to get information regarding LAST_PROJECT_DIR. For example, to extract the project name.

if LAST_PROJECT_DIR != nil then
    local last_project_name = Session.info(LAST_PROJECT_DIR).project.name 
end
GnikDroy commented 1 year ago

If you could visit a project's directory without 'officially' being in a project, you could edit one or two files and avoid overwriting your session, which you might have wanted to return to later, or even immediately afterwards by using the project browser.

A problem like this is partly self-inflicted, I believe. You control exactly when projections switches projects. You control exactly when projections stores a session file, and exactly when it restores an existing session. After all, projections does 0 work by default 😄. So you control what it means to be "officially" in a project.

If you find your session files to be overridden often, and by mistake, then you need to figure out which autocmd is doing that. And refine that. Heck, you can just use switcher to switch between projects and remove all autocmds (apart from the VimLeavePre that stores your session).

Gazareth commented 1 year ago

Forgive me if I am mistaken but I don't think the restore hook is called when loading a project for the first time, since there will be no session yet.

On Mon, 9 Jan 2023, 12:40 Gnik, @.***> wrote:

If you could visit a project's directory without 'officially' being in a project, you could edit one or two files and avoid overwriting your session, which you might have wanted to return to later, or even immediately afterwards by using the project browser.

A problem like this is partly self-inflicted, I believe. You control exactly when projections switches projects. You control exactly when projections stores a session file, and exactly when it restores an existing session. After all, projections does 0 work by default 😄. So you control what it means to be "officially" in a project.

If you find your session files to be overridden often, and by mistake, then you need to figure out which autocmd is doing that. And refine that. Heck, you can just use switcher to switch between projects and remove all autocmds (apart from the VimLeavePre that stores your session).

— Reply to this email directly, view it on GitHub https://github.com/GnikDroy/projections.nvim/issues/27#issuecomment-1375568288, or unsubscribe https://github.com/notifications/unsubscribe-auth/AC24AWYOUUX6P7LD6UYO42TWRQBLJANCNFSM6AAAAAATUYC4MU . You are receiving this because you were mentioned.Message ID: @.***>

GnikDroy commented 1 year ago

Yes, you are correct. The restore hook will be called only on restoring sessions. If no session is present, then it won't be called.

If you want to track (no session) cases as well, you will need to hook into switcher.switch.

local switcher = require("projections.switcher")
local original_switch_function = switcher.switch

switcher.switch = function(...)
    local operation_successful = original_switch_function(...)
    if operation_successful then
        LAST_PROJECT_DIR = vim.loop.cwd()
    end
    return operation_successful
end

It is a bit hacky though.

I am not 100% opposed to the idea of require('projections.switcher').current_project(). I just want to make sure it is a feature that is used. I need to plan before exposing a function, because removing the function in the future results in a breaking change.

By hooking into the switcher.switch function yourself, you can achieve this from your side. You can also do other things like perform additional checks before switching projects, run (git) commands when you switch projects .... etc

That being said, if you want to add this, send in a PR, and I will take a look. No pressure though. If you don't have time to implement this, I will take a look when I'm free. I do hope you consider the above snippet though. 😄