Skip to content

Commit 1fc963d

Browse files
committed
feature: change worktree on all buffers
Change update_current_buffer function to update all currently open buffers and de-list buffers from the previous worktree. Buffers from files that don't exist on another worktree will only be de-listed. Buffers unrelated to the worktree (temporary or external files) should ignored The focused buffer file will be kept focused on the new worktree, unless if it doesn't exist, in which case it will select the last one. In the future, it would also be possible to remember closed files that don't exist for when you switch back, that's not addressed by this PR Also fixes #84
1 parent d7f4e25 commit 1fc963d

File tree

1 file changed

+56
-30
lines changed

1 file changed

+56
-30
lines changed

lua/git-worktree/init.lua

Lines changed: 56 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ M.setup_git_info = function()
5050
git_worktree_root = cwd
5151
else
5252
local start = stdout:find("%.git")
53-
git_worktree_root = stdout:sub(1,start - 2)
53+
git_worktree_root = stdout:sub(1, start - 2)
5454
end
5555
else
5656
local start = stdout:find("/worktrees/")
@@ -157,7 +157,7 @@ local function change_dirs(path)
157157
vim.cmd(cmd)
158158
current_worktree_path = worktree_path
159159
else
160-
status:error('Could not chang to directory: ' ..worktree_path)
160+
status:error('Could not chang to directory: ' .. worktree_path)
161161
end
162162

163163
if M._config.clearjumps_on_change then
@@ -171,7 +171,7 @@ end
171171
local function create_worktree_job(path, branch, found_branch)
172172

173173
local worktree_add_cmd = 'git'
174-
local worktree_add_args = {'worktree', 'add'}
174+
local worktree_add_args = { 'worktree', 'add' }
175175

176176
if not found_branch then
177177
table.insert(worktree_add_args, '-b')
@@ -277,7 +277,7 @@ local function has_branch(branch, cb)
277277
local job = Job:new({
278278
'git', 'branch', on_stdout = function(_, data)
279279
-- remove markere on current branch
280-
data = data:gsub("*","")
280+
data = data:gsub("*", "")
281281
data = vim.trim(data)
282282
found = found or data == branch
283283
end,
@@ -311,7 +311,7 @@ local function create_worktree(path, branch, upstream, found_branch)
311311
})
312312

313313
local set_branch_cmd = 'git'
314-
local set_branch_args= {'branch', string.format('--set-upstream-to=%s/%s', upstream, branch)}
314+
local set_branch_args = { 'branch', string.format('--set-upstream-to=%s/%s', upstream, branch) }
315315
local set_branch = Job:new({
316316
command = set_branch_cmd,
317317
args = set_branch_args,
@@ -323,9 +323,9 @@ local function create_worktree(path, branch, upstream, found_branch)
323323

324324
-- TODO: How to configure origin??? Should upstream ever be the push
325325
-- destination?
326-
local set_push_cmd = 'git'
327-
local set_push_args = {'push', "--set-upstream", upstream, branch, path}
328-
local set_push = Job:new({
326+
local set_push_cmd = 'git'
327+
local set_push_args = { 'push', "--set-upstream", upstream, branch, path }
328+
local set_push = Job:new({
329329
command = set_push_cmd,
330330
args = set_push_args,
331331
cwd = worktree_path,
@@ -368,14 +368,14 @@ local function create_worktree(path, branch, upstream, found_branch)
368368
end
369369

370370
vim.schedule(function()
371-
emit_on_change(Enum.Operations.Create, {path = path, branch = branch, upstream = upstream})
371+
emit_on_change(Enum.Operations.Create, { path = path, branch = branch, upstream = upstream })
372372
M.switch_worktree(path)
373373
end)
374374
end)
375375
else
376376
create:after(function()
377377
vim.schedule(function()
378-
emit_on_change(Enum.Operations.Create, {path = path, branch = branch, upstream = upstream})
378+
emit_on_change(Enum.Operations.Create, { path = path, branch = branch, upstream = upstream })
379379
M.switch_worktree(path)
380380
end)
381381
end)
@@ -478,34 +478,60 @@ M.update_current_buffer = function(prev_path)
478478
return false
479479
end
480480

481+
local buffers = vim.api.nvim_list_bufs()
482+
local listed_buffers = vim.tbl_filter(function(bufn)
483+
return vim.api.nvim_buf_is_valid(bufn) and vim.api.nvim_buf_get_option(bufn, 'buflisted')
484+
end, buffers)
485+
486+
local changed = false
487+
local current_buf_name = vim.api.nvim_buf_get_name(vim.api.nvim_get_current_buf())
488+
local new_current_buf = 0
489+
481490
local cwd = vim.loop.cwd()
482-
local current_buf_name = vim.api.nvim_buf_get_name(0)
483-
if not current_buf_name or current_buf_name == "" then
484-
return false
485-
end
491+
for _, existing_buffer in ipairs(listed_buffers) do
492+
local buf_name = vim.api.nvim_buf_get_name(existing_buffer)
493+
if not buf_name or buf_name == "" then
494+
goto continue
495+
end
486496

487-
local name = Path:new(current_buf_name):absolute()
488-
local start, fin = string.find(name, cwd..Path.path.sep, 1, true)
489-
if start ~= nil then
490-
return true
491-
end
497+
local name = Path:new(buf_name):absolute()
498+
local start, fin = string.find(name, cwd .. Path.path.sep, 1, true)
499+
if start ~= nil then
500+
changed = true
501+
goto continue
502+
end
492503

493-
start, fin = string.find(name, prev_path, 1, true)
494-
if start == nil then
495-
return false
496-
end
504+
start, fin = string.find(name, prev_path, 1, true)
505+
if start == nil then
506+
goto continue
507+
end
497508

498-
local local_name = name:sub(fin + 2)
509+
-- de-list buffer if it's related to the old worktree
510+
vim.api.nvim_buf_set_option(existing_buffer, 'buflisted', false)
499511

500-
local final_path = Path:new({cwd, local_name}):absolute()
512+
local local_name = name:sub(fin + 2)
501513

502-
if not Path:new(final_path):exists() then
503-
return false
514+
local final_path = Path:new({ cwd, local_name }):absolute()
515+
516+
if not Path:new(final_path):exists() then
517+
goto continue
518+
end
519+
520+
local new_buffer = vim.fn.bufnr(final_path, true)
521+
vim.api.nvim_buf_set_option(new_buffer, 'buflisted', true)
522+
vim.api.nvim_set_current_buf(new_buffer)
523+
524+
if current_buf_name == buf_name then
525+
new_current_buf = new_buffer
526+
end
527+
528+
changed = true
529+
530+
::continue::
504531
end
532+
vim.api.nvim_set_current_buf(new_current_buf)
505533

506-
local bufnr = vim.fn.bufnr(final_path, true)
507-
vim.api.nvim_set_current_buf(bufnr)
508-
return true
534+
return changed
509535
end
510536

511537
M.on_tree_change = function(cb)

0 commit comments

Comments
 (0)