Skip to content

Commit 9fdb565

Browse files
committed
fix(cwd): multiple cwd changes
1 parent 73b4241 commit 9fdb565

3 files changed

Lines changed: 40 additions & 18 deletions

File tree

lua/opencode/core.lua

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -545,28 +545,41 @@ end
545545

546546
--- Handle working directory changes by restarting the server and loading the appropriate session.
547547
--- This function performs the following steps:
548-
--- 1. Shuts down the existing opencode server
549-
--- 2. Starts a new server instance
550-
--- 3. Clears the active session and context
551-
--- 4. Loads the last workspace session for the new directory, or creates a new one if none exists
552548
--- @return Promise<void>
553549
M.handle_directory_change = Promise.async(function()
554550
local log = require('opencode.log')
555551

556552
if state.opencode_server then
557553
vim.notify('Directory changed, restarting Opencode server...', vim.log.levels.INFO)
558554
log.info('Shutting down Opencode server due to directory change...')
555+
559556
state.opencode_server:shutdown():await()
560-
server_job.ensure_server():await()
561-
state.active_session = nil
562-
vim.notify('Loading last session for new working dir', vim.log.levels.INFO)
563-
state.last_sent_context = nil
564-
context.unload_attachments()
565-
566-
state.active_session = session.get_last_workspace_session():await()
567-
if not state.active_session then
568-
state.active_session = M.create_new_session():await()
569-
end
557+
558+
vim.defer_fn(
559+
Promise.async(function()
560+
state.opencode_server = nil
561+
server_job.ensure_server():await()
562+
563+
vim.notify('Loading last session for new working dir [' .. vim.fn.getcwd() .. ']', vim.log.levels.INFO)
564+
565+
state.active_session = nil
566+
state.last_sent_context = nil
567+
context.unload_attachments()
568+
569+
local is_new = false
570+
state.active_session = session.get_last_workspace_session():await()
571+
572+
if not state.active_session then
573+
is_new = true
574+
state.active_session = M.create_new_session():await()
575+
end
576+
577+
log.debug(
578+
'Loaded session for new working dir' .. vim.inspect({ session = state.active_session, is_new = is_new })
579+
)
580+
end),
581+
200
582+
)
570583
end
571584
end)
572585

lua/opencode/ui/autocmds.lua

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,12 @@ function M.setup_autocmds(windows)
4949
end,
5050
})
5151

52-
vim.api.nvim_create_autocmd('DirChanged', {
52+
vim.api.nvim_create_autocmd('DirChangedPre', {
5353
group = group,
54-
callback = Promise.async(function(event)
54+
callback = function(event)
5555
local core = require('opencode.core')
56-
core.handle_directory_change():await()
57-
end),
56+
core.handle_directory_change()
57+
end,
5858
})
5959

6060
if require('opencode.config').ui.position == 'current' then

tests/unit/core_spec.lua

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,10 +472,18 @@ describe('opencode.core', function()
472472
describe('handle_directory_change', function()
473473
local server_job
474474
local context
475+
local original_defer_fn
475476

476477
before_each(function()
477478
server_job = require('opencode.server_job')
478479
context = require('opencode.context')
480+
original_defer_fn = vim.defer_fn
481+
482+
-- Mock vim.defer_fn to execute immediately in tests
483+
vim.defer_fn = function(fn, delay)
484+
fn()
485+
end
486+
479487
stub(server_job, 'ensure_server').invokes(function()
480488
local p = Promise.new()
481489
p:resolve({
@@ -493,6 +501,7 @@ describe('opencode.core', function()
493501
end)
494502

495503
after_each(function()
504+
vim.defer_fn = original_defer_fn
496505
if server_job.ensure_server.revert then
497506
server_job.ensure_server:revert()
498507
end

0 commit comments

Comments
 (0)