Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 43 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,12 +120,16 @@ or with lua
## Hooks

You can provide hooks to perform additional actions on worktree addition, removal and switching

```lua
require('worktrees').setup {
hooks = {
on_add = function(name, path, branch)
-- your action here
end,
on_before_switch = function(from, to, git_path_info)
-- your action here
end,
on_switch = function(from, to, git_path_info)
-- your action here
end,
Expand Down Expand Up @@ -170,6 +174,44 @@ require('worktrees').setup {
}

```

### Example - per-worktree sessions using `mini.sessions`

```lua
require('worktrees').setup {
swap_current_buffer = false,
hooks = {
on_before_switch = function(from, to, git_path_info)
-- Persist worktree session before worktree switch.
MiniSessions.write(nil, { force = true, verbose = false })
vim.cmd('silent! %bwipeout!')

-- Prevent dangling LSP sessions.
vim.lsp.stop_client(vim.lsp.get_clients())

-- Out of the box, worktrees.nvim changes a working directory on worktree switch.
-- Optionally, you may prevent this by returning "false".
-- return false
end,
on_switch = function(from, to, git_path_info)
-- Restore session after worktree changes.
if vim.fn.filereadable(MiniSessions.config.file) then
MiniSessions.read(nil, { force = true, verbose = false })
end
end,
on_before_remove = function(path)
if path ~= vim.loop.cwd() or vim.v.this_session == '' then
return
end

-- Detach session if active worktree will be removed.
MiniSessions.delete(nil, { force = true, verbose = false })
vim.v.this_session = ''
end
}
}
```

## Telescope

The extension can be loaded with telescope
Expand Down Expand Up @@ -226,4 +268,4 @@ git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"

## TODO

- [ ] Options to customize behavior
- [ ] Options to customize behavior
25 changes: 22 additions & 3 deletions lua/worktrees/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ local utils = require("worktrees.utils")
local status = require("worktrees.status")

---@class worktrees.Hooks
---@field on_before_switch fun(from: string, to: string, git_path_info: worktrees.GitPathInfo): boolean | nil
---@field on_switch fun(from: string, to: string, git_path_info: worktrees.GitPathInfo)
---@field on_add fun(name: string, path: string, branch: string)
---@field on_remove fun(name: string)
---@field on_add fun(name: string, path: string, branch: string) | nil
---@field on_before_remove fun(path: string) | nil
---@field on_remove fun(name: string) | nil

---@class worktrees.Options
---@field hooks? worktrees.Hooks,
Expand Down Expand Up @@ -162,6 +164,20 @@ M.switch_worktree = function(path)
end

vim.schedule(function()
local prev_path = vim.loop.cwd() --[[@as string]]

if M._options.hooks.on_before_switch then
-- on_before_switch can intercept worktree switch logic if returns 'false'.
local continue = M._options.hooks.on_before_switch(
prev_path,
found_path,
before_git_path_info
)
if continue ~= nil and not continue then
return
end
end

-- Clear jumplist so that no file in the old worktree is present
-- in the jumplist for accidental switching of worktrees
vim.cmd("clearjumps")
Expand All @@ -177,7 +193,6 @@ M.switch_worktree = function(path)

-- Change neovim cwd
if M._options.hooks.on_switch then
local prev_path = vim.loop.cwd() --[[@as string]]
vim.cmd("cd " .. found_path)
M._options.hooks.on_switch(
prev_path,
Expand Down Expand Up @@ -211,6 +226,10 @@ M.remove_worktree = function(path)
return
end

if M._options.hooks.on_before_remove then
M._options.hooks.on_before_remove(found_path)
end

if found_path == vim.loop.cwd() then
local before_git_path_info = utils.get_git_path_info()
if before_git_path_info == nil then
Expand Down