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