@@ -19,6 +19,10 @@ local defaults = {
19
19
auto_close = true ,
20
20
env = {},
21
21
snacks_win_opts = {},
22
+ -- Working directory control
23
+ cwd = nil , -- static cwd override
24
+ git_repo_cwd = false , -- resolve to git root when spawning
25
+ cwd_provider = nil , -- function(ctx) -> cwd string
22
26
}
23
27
24
28
M .defaults = defaults
@@ -191,18 +195,67 @@ local function build_config(opts_override)
191
195
snacks_win_opts = function (val )
192
196
return type (val ) == " table"
193
197
end ,
198
+ cwd = function (val )
199
+ return val == nil or type (val ) == " string"
200
+ end ,
201
+ git_repo_cwd = function (val )
202
+ return type (val ) == " boolean"
203
+ end ,
204
+ cwd_provider = function (val )
205
+ local t = type (val )
206
+ if t == " function" then
207
+ return true
208
+ end
209
+ if t == " table" then
210
+ local mt = getmetatable (val )
211
+ return mt and mt .__call ~= nil
212
+ end
213
+ return false
214
+ end ,
194
215
}
195
216
for key , val in pairs (opts_override ) do
196
217
if effective_config [key ] ~= nil and validators [key ] and validators [key ](val ) then
197
218
effective_config [key ] = val
198
219
end
199
220
end
200
221
end
222
+ -- Resolve cwd at config-build time so providers receive it directly
223
+ local cwd_ctx = {
224
+ file = (function ()
225
+ local path = vim .fn .expand (" %:p" )
226
+ if type (path ) == " string" and path ~= " " then
227
+ return path
228
+ end
229
+ return nil
230
+ end )(),
231
+ cwd = vim .fn .getcwd (),
232
+ }
233
+ cwd_ctx .file_dir = cwd_ctx .file and vim .fn .fnamemodify (cwd_ctx .file , " :h" ) or nil
234
+
235
+ local resolved_cwd = nil
236
+ -- Prefer provider function, then static cwd, then git root via resolver
237
+ if effective_config .cwd_provider then
238
+ local ok_p , res = pcall (effective_config .cwd_provider , cwd_ctx )
239
+ if ok_p and type (res ) == " string" and res ~= " " then
240
+ resolved_cwd = vim .fn .expand (res )
241
+ end
242
+ end
243
+ if not resolved_cwd and type (effective_config .cwd ) == " string" and effective_config .cwd ~= " " then
244
+ resolved_cwd = vim .fn .expand (effective_config .cwd )
245
+ end
246
+ if not resolved_cwd and effective_config .git_repo_cwd then
247
+ local ok_r , cwd_mod = pcall (require , " claudecode.cwd" )
248
+ if ok_r and cwd_mod and type (cwd_mod .git_root ) == " function" then
249
+ resolved_cwd = cwd_mod .git_root (cwd_ctx .file_dir or cwd_ctx .cwd )
250
+ end
251
+ end
252
+
201
253
return {
202
254
split_side = effective_config .split_side ,
203
255
split_width_percentage = effective_config .split_width_percentage ,
204
256
auto_close = effective_config .auto_close ,
205
257
snacks_win_opts = effective_config .snacks_win_opts ,
258
+ cwd = resolved_cwd ,
206
259
}
207
260
end
208
261
@@ -319,9 +372,30 @@ function M.setup(user_term_config, p_terminal_cmd, p_env)
319
372
end
320
373
321
374
for k , v in pairs (user_term_config ) do
322
- if k == " terminal_cmd" then
323
- -- terminal_cmd is handled above, skip
324
- break
375
+ if k == " split_side" then
376
+ if v == " left" or v == " right" then
377
+ defaults .split_side = v
378
+ else
379
+ vim .notify (" claudecode.terminal.setup: Invalid value for split_side: " .. tostring (v ), vim .log .levels .WARN )
380
+ end
381
+ elseif k == " split_width_percentage" then
382
+ if type (v ) == " number" and v > 0 and v < 1 then
383
+ defaults .split_width_percentage = v
384
+ else
385
+ vim .notify (
386
+ " claudecode.terminal.setup: Invalid value for split_width_percentage: " .. tostring (v ),
387
+ vim .log .levels .WARN
388
+ )
389
+ end
390
+ elseif k == " provider" then
391
+ if type (v ) == " table" or v == " snacks" or v == " native" or v == " external" or v == " auto" then
392
+ defaults .provider = v
393
+ else
394
+ vim .notify (
395
+ " claudecode.terminal.setup: Invalid value for provider: " .. tostring (v ) .. " . Defaulting to 'native'." ,
396
+ vim .log .levels .WARN
397
+ )
398
+ end
325
399
elseif k == " provider_opts" then
326
400
-- Handle nested provider options
327
401
if type (v ) == " table" then
@@ -344,26 +418,60 @@ function M.setup(user_term_config, p_terminal_cmd, p_env)
344
418
else
345
419
vim .notify (" claudecode.terminal.setup: Invalid value for provider_opts: " .. tostring (v ), vim .log .levels .WARN )
346
420
end
347
- elseif defaults [k ] ~= nil then -- Other known config keys
348
- if k == " split_side" and (v == " left" or v == " right" ) then
349
- defaults [k ] = v
350
- elseif k == " split_width_percentage" and type (v ) == " number" and v > 0 and v < 1 then
351
- defaults [k ] = v
352
- elseif
353
- k == " provider" and (v == " snacks" or v == " native" or v == " external" or v == " auto" or type (v ) == " table" )
354
- then
355
- defaults [k ] = v
356
- elseif k == " show_native_term_exit_tip" and type (v ) == " boolean" then
357
- defaults [k ] = v
358
- elseif k == " auto_close" and type (v ) == " boolean" then
359
- defaults [k ] = v
360
- elseif k == " snacks_win_opts" and type (v ) == " table" then
361
- defaults [k ] = v
421
+ elseif k == " show_native_term_exit_tip" then
422
+ if type (v ) == " boolean" then
423
+ defaults .show_native_term_exit_tip = v
424
+ else
425
+ vim .notify (
426
+ " claudecode.terminal.setup: Invalid value for show_native_term_exit_tip: " .. tostring (v ),
427
+ vim .log .levels .WARN
428
+ )
429
+ end
430
+ elseif k == " auto_close" then
431
+ if type (v ) == " boolean" then
432
+ defaults .auto_close = v
433
+ else
434
+ vim .notify (" claudecode.terminal.setup: Invalid value for auto_close: " .. tostring (v ), vim .log .levels .WARN )
435
+ end
436
+ elseif k == " snacks_win_opts" then
437
+ if type (v ) == " table" then
438
+ defaults .snacks_win_opts = v
439
+ else
440
+ vim .notify (" claudecode.terminal.setup: Invalid value for snacks_win_opts" , vim .log .levels .WARN )
441
+ end
442
+ elseif k == " cwd" then
443
+ if v == nil or type (v ) == " string" then
444
+ defaults .cwd = v
445
+ else
446
+ vim .notify (" claudecode.terminal.setup: Invalid value for cwd: " .. tostring (v ), vim .log .levels .WARN )
447
+ end
448
+ elseif k == " git_repo_cwd" then
449
+ if type (v ) == " boolean" then
450
+ defaults .git_repo_cwd = v
362
451
else
363
- vim .notify (" claudecode.terminal.setup: Invalid value for " .. k .. " : " .. tostring (v ), vim .log .levels .WARN )
452
+ vim .notify (" claudecode.terminal.setup: Invalid value for git_repo_cwd: " .. tostring (v ), vim .log .levels .WARN )
453
+ end
454
+ elseif k == " cwd_provider" then
455
+ local t = type (v )
456
+ if t == " function" then
457
+ defaults .cwd_provider = v
458
+ elseif t == " table" then
459
+ local mt = getmetatable (v )
460
+ if mt and mt .__call then
461
+ defaults .cwd_provider = v
462
+ else
463
+ vim .notify (
464
+ " claudecode.terminal.setup: cwd_provider table is not callable (missing __call)" ,
465
+ vim .log .levels .WARN
466
+ )
467
+ end
468
+ else
469
+ vim .notify (" claudecode.terminal.setup: Invalid cwd_provider type: " .. tostring (t ), vim .log .levels .WARN )
364
470
end
365
471
else
366
- vim .notify (" claudecode.terminal.setup: Unknown configuration key: " .. k , vim .log .levels .WARN )
472
+ if k ~= " terminal_cmd" then
473
+ vim .notify (" claudecode.terminal.setup: Unknown configuration key: " .. k , vim .log .levels .WARN )
474
+ end
367
475
end
368
476
end
369
477
0 commit comments