@@ -16,6 +16,10 @@ local defaults = {
16
16
auto_close = true ,
17
17
env = {},
18
18
snacks_win_opts = {},
19
+ -- Working directory control
20
+ cwd = nil , -- static cwd override
21
+ git_repo_cwd = false , -- resolve to git root when spawning
22
+ cwd_provider = nil , -- function(ctx) -> cwd string
19
23
}
20
24
21
25
M .defaults = defaults
@@ -172,18 +176,67 @@ local function build_config(opts_override)
172
176
snacks_win_opts = function (val )
173
177
return type (val ) == " table"
174
178
end ,
179
+ cwd = function (val )
180
+ return val == nil or type (val ) == " string"
181
+ end ,
182
+ git_repo_cwd = function (val )
183
+ return type (val ) == " boolean"
184
+ end ,
185
+ cwd_provider = function (val )
186
+ local t = type (val )
187
+ if t == " function" then
188
+ return true
189
+ end
190
+ if t == " table" then
191
+ local mt = getmetatable (val )
192
+ return mt and mt .__call ~= nil
193
+ end
194
+ return false
195
+ end ,
175
196
}
176
197
for key , val in pairs (opts_override ) do
177
198
if effective_config [key ] ~= nil and validators [key ] and validators [key ](val ) then
178
199
effective_config [key ] = val
179
200
end
180
201
end
181
202
end
203
+ -- Resolve cwd at config-build time so providers receive it directly
204
+ local cwd_ctx = {
205
+ file = (function ()
206
+ local path = vim .fn .expand (" %:p" )
207
+ if type (path ) == " string" and path ~= " " then
208
+ return path
209
+ end
210
+ return nil
211
+ end )(),
212
+ cwd = vim .fn .getcwd (),
213
+ }
214
+ cwd_ctx .file_dir = cwd_ctx .file and vim .fn .fnamemodify (cwd_ctx .file , " :h" ) or nil
215
+
216
+ local resolved_cwd = nil
217
+ -- Prefer provider function, then static cwd, then git root via resolver
218
+ if effective_config .cwd_provider then
219
+ local ok_p , res = pcall (effective_config .cwd_provider , cwd_ctx )
220
+ if ok_p and type (res ) == " string" and res ~= " " then
221
+ resolved_cwd = vim .fn .expand (res )
222
+ end
223
+ end
224
+ if not resolved_cwd and type (effective_config .cwd ) == " string" and effective_config .cwd ~= " " then
225
+ resolved_cwd = vim .fn .expand (effective_config .cwd )
226
+ end
227
+ if not resolved_cwd and effective_config .git_repo_cwd then
228
+ local ok_r , cwd_mod = pcall (require , " claudecode.cwd" )
229
+ if ok_r and cwd_mod and type (cwd_mod .git_root ) == " function" then
230
+ resolved_cwd = cwd_mod .git_root (cwd_ctx .file_dir or cwd_ctx .cwd )
231
+ end
232
+ end
233
+
182
234
return {
183
235
split_side = effective_config .split_side ,
184
236
split_width_percentage = effective_config .split_width_percentage ,
185
237
auto_close = effective_config .auto_close ,
186
238
snacks_win_opts = effective_config .snacks_win_opts ,
239
+ cwd = resolved_cwd ,
187
240
}
188
241
end
189
242
@@ -300,24 +353,84 @@ function M.setup(user_term_config, p_terminal_cmd, p_env)
300
353
end
301
354
302
355
for k , v in pairs (user_term_config ) do
303
- if defaults [k ] ~= nil and k ~= " terminal_cmd" then -- terminal_cmd is handled above
304
- if k == " split_side" and (v == " left" or v == " right" ) then
305
- defaults [k ] = v
306
- elseif k == " split_width_percentage" and type (v ) == " number" and v > 0 and v < 1 then
307
- defaults [k ] = v
308
- elseif k == " provider" and (v == " snacks" or v == " native" or v == " auto" or type (v ) == " table" ) then
309
- defaults [k ] = v
310
- elseif k == " show_native_term_exit_tip" and type (v ) == " boolean" then
311
- defaults [k ] = v
312
- elseif k == " auto_close" and type (v ) == " boolean" then
313
- defaults [k ] = v
314
- elseif k == " snacks_win_opts" and type (v ) == " table" then
315
- defaults [k ] = v
356
+ if k == " split_side" then
357
+ if v == " left" or v == " right" then
358
+ defaults .split_side = v
359
+ else
360
+ vim .notify (" claudecode.terminal.setup: Invalid value for split_side: " .. tostring (v ), vim .log .levels .WARN )
361
+ end
362
+ elseif k == " split_width_percentage" then
363
+ if type (v ) == " number" and v > 0 and v < 1 then
364
+ defaults .split_width_percentage = v
365
+ else
366
+ vim .notify (
367
+ " claudecode.terminal.setup: Invalid value for split_width_percentage: " .. tostring (v ),
368
+ vim .log .levels .WARN
369
+ )
370
+ end
371
+ elseif k == " provider" then
372
+ if type (v ) == " table" or v == " snacks" or v == " native" or v == " auto" then
373
+ defaults .provider = v
316
374
else
317
- vim .notify (" claudecode.terminal.setup: Invalid value for " .. k .. " : " .. tostring (v ), vim .log .levels .WARN )
375
+ vim .notify (
376
+ " claudecode.terminal.setup: Invalid value for provider: " .. tostring (v ) .. " . Defaulting to 'native'." ,
377
+ vim .log .levels .WARN
378
+ )
379
+ end
380
+ elseif k == " show_native_term_exit_tip" then
381
+ if type (v ) == " boolean" then
382
+ defaults .show_native_term_exit_tip = v
383
+ else
384
+ vim .notify (
385
+ " claudecode.terminal.setup: Invalid value for show_native_term_exit_tip: " .. tostring (v ),
386
+ vim .log .levels .WARN
387
+ )
388
+ end
389
+ elseif k == " auto_close" then
390
+ if type (v ) == " boolean" then
391
+ defaults .auto_close = v
392
+ else
393
+ vim .notify (" claudecode.terminal.setup: Invalid value for auto_close: " .. tostring (v ), vim .log .levels .WARN )
394
+ end
395
+ elseif k == " snacks_win_opts" then
396
+ if type (v ) == " table" then
397
+ defaults .snacks_win_opts = v
398
+ else
399
+ vim .notify (" claudecode.terminal.setup: Invalid value for snacks_win_opts" , vim .log .levels .WARN )
400
+ end
401
+ elseif k == " cwd" then
402
+ if v == nil or type (v ) == " string" then
403
+ defaults .cwd = v
404
+ else
405
+ vim .notify (" claudecode.terminal.setup: Invalid value for cwd: " .. tostring (v ), vim .log .levels .WARN )
406
+ end
407
+ elseif k == " git_repo_cwd" then
408
+ if type (v ) == " boolean" then
409
+ defaults .git_repo_cwd = v
410
+ else
411
+ vim .notify (" claudecode.terminal.setup: Invalid value for git_repo_cwd: " .. tostring (v ), vim .log .levels .WARN )
412
+ end
413
+ elseif k == " cwd_provider" then
414
+ local t = type (v )
415
+ if t == " function" then
416
+ defaults .cwd_provider = v
417
+ elseif t == " table" then
418
+ local mt = getmetatable (v )
419
+ if mt and mt .__call then
420
+ defaults .cwd_provider = v
421
+ else
422
+ vim .notify (
423
+ " claudecode.terminal.setup: cwd_provider table is not callable (missing __call)" ,
424
+ vim .log .levels .WARN
425
+ )
426
+ end
427
+ else
428
+ vim .notify (" claudecode.terminal.setup: Invalid cwd_provider type: " .. tostring (t ), vim .log .levels .WARN )
429
+ end
430
+ else
431
+ if k ~= " terminal_cmd" then
432
+ vim .notify (" claudecode.terminal.setup: Unknown configuration key: " .. k , vim .log .levels .WARN )
318
433
end
319
- elseif k ~= " terminal_cmd" then -- Avoid warning for terminal_cmd if passed in user_term_config
320
- vim .notify (" claudecode.terminal.setup: Unknown configuration key: " .. k , vim .log .levels .WARN )
321
434
end
322
435
end
323
436
0 commit comments