project.nvim icon indicating copy to clipboard operation
project.nvim copied to clipboard

Feat: Allow creation of custom callbacks, executed before and after project selection.

Open jakemason opened this issue 3 years ago • 8 comments

Hi all,

This is a quick change that allows users to create a custom callback that executes after a project is selected. I believe this helps push toward a solution for #73 #76 and maybe #49.

For example, I use the following with vim-obsession:

local function loadSession()
 if(vim.fn.filereadable('Session.vim') ~= 0) then
   -- start a new scratch file just to stop nvim from throwing a floating
   -- window error if we attempt to source without having a non-floating 
   -- buffer open
   vim.cmd('new | setlocal bt=nofile bh=wipe nobl noswapfile nu')
   
   -- source our Session.vim file and ignore the error about closing the
   -- scratch file above so abruptly
   vim.cmd('silent! source Session.vim')
  end
end

and that gets assigned in the setup() call as follows:

require("project_nvim").setup { 
  detection_methods = { "pattern" },
  patterns = { ".git", ".svn" },  -- only register versioning roots as projects
  custom_callback = loadSession
}

Ideally, I think this could be expanded to allow for custom commands per project but I didn't know if that was realistically possible. It could probably be achieved by passing a table where the key is the name of the project and the value is the function to execute, but I wasn't able to find a way to get the project name from telescope. Additionally, this possible addition would be brittle because two projects could potentially share the same name. I also don't think we can use the promt_bufnr because there's not a user-friendly way of really managing that AFAIK.

That said, we could also just pass these responsibilities onto the user to figure out conditionals with their custom callback.

Regardless, this pull request works for me and I think will be of aid to others.

Happy to make any changes or updates as needed!

UPDATE: Please see my comment below on how this has changed to allow a callback when closing a project and when opening one.

Cheers, Jake

jakemason avatar Jun 25 '22 03:06 jakemason

Can I suggest having a callback on project close as well? This way we can do cleanup also.

midrare avatar Jul 07 '22 01:07 midrare

I'm not opposed to the idea at all, but if I work on that it'll likely be in a separate pull request. Let's see if this is something the maintainers are willing to add at all before I add additional features. It's a great idea though!

jakemason avatar Jul 07 '22 19:07 jakemason

Will this get merged @ahmedkhalf?

alexander-born avatar Dec 01 '22 13:12 alexander-born

I've updated this to now allow a custom callback to occur both before and after the project context switch. This was important for me because it lets me automatically switch between Session.vim files automatically without the tracking of one project polluting the other.

My setup is as follows:

local function closeSession()
 -- if we're currently tracking in an active project, we want to pause that
 -- by calling Obsess before we open the next project. If we don't project #2
 -- will track the session in project #1's Session.vim file
 if vim.g.this_obsession then
  vim.cmd('silent! Obsess')
 end
end

local function loadSession()
 -- store the project directory we just switched into because our bwipeout call
 -- below will change it again and we need to switch to it after the clear out
 project_directory = vim.fn.getcwd(); 
 -- need to wipeout all open buffers or Telescope lingers on the last project
 vim.cmd('silent! bufdo! bwipeout') 
 vim.cmd('cd ' .. project_directory)
 if(vim.fn.filereadable('Session.vim') ~= 0) then
   -- start a new scratch file just to stop nvim from throwing a floating
   -- window error if we attempt to source without having a non-floating 
   -- buffer open
   vim.cmd('new | setlocal bt=nofile bh=wipe nobl noswapfile nu')
   
   -- source our Session.vim file and ignore the error about closing the
   -- scratch file above so abruptly
   vim.cmd('silent! source Session.vim')

   -- escapes from Insert mode, which the source call above will leave us in by default
   vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes('<esc>',true,false,true),'m',true)
  end
end

-- Session information
vim.o.sessionoptions="blank,buffers,curdir,folds,help,tabpages,winsize,winpos,terminal"
require("project_nvim").setup { 
  detection_methods = { "pattern" },
  patterns = { ".git", ".svn" },  -- only register versioning roots as projects
  after_project_selection_callback = loadSession,
  before_project_selection_callback = closeSession
}

While it looks like this might not ever get merged, I figured this is probably helpful to someone out there based on the feedback this pull request has received!

Cheers, Jake

Also just tagging @mediumrarez as they originally requested something like this :)

jakemason avatar Feb 16 '23 03:02 jakemason

Commenting here to know if @ahmedkhalf intends to review this. Do we have additional maintainers?

ditsuke avatar May 08 '23 20:05 ditsuke

after_project_selection_callback not work, it is ready to merge?

malishengo avatar Sep 05 '23 01:09 malishengo

The feature works for me and the use case listed above, and still does as of last week's nightly Neovim release so you'll have to provide a repro case if you want a pair of eyes on it. The timing of the switch is a little awkward within Telescope so some things may not behave as you expect.

jakemason avatar Sep 05 '23 02:09 jakemason