@@ -19,6 +19,10 @@ local defaults = {
1919 auto_close = true ,
2020 env = {},
2121 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
2226}
2327
2428M .defaults = defaults
@@ -197,18 +201,67 @@ local function build_config(opts_override)
197201 snacks_win_opts = function (val )
198202 return type (val ) == " table"
199203 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 ,
200221 }
201222 for key , val in pairs (opts_override ) do
202223 if effective_config [key ] ~= nil and validators [key ] and validators [key ](val ) then
203224 effective_config [key ] = val
204225 end
205226 end
206227 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+
207259 return {
208260 split_side = effective_config .split_side ,
209261 split_width_percentage = effective_config .split_width_percentage ,
210262 auto_close = effective_config .auto_close ,
211263 snacks_win_opts = effective_config .snacks_win_opts ,
264+ cwd = resolved_cwd ,
212265 }
213266end
214267
@@ -325,9 +378,30 @@ function M.setup(user_term_config, p_terminal_cmd, p_env)
325378 end
326379
327380 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
331405 elseif k == " provider_opts" then
332406 -- Handle nested provider options
333407 if type (v ) == " table" then
@@ -350,26 +424,60 @@ function M.setup(user_term_config, p_terminal_cmd, p_env)
350424 else
351425 vim .notify (" claudecode.terminal.setup: Invalid value for provider_opts: " .. tostring (v ), vim .log .levels .WARN )
352426 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
368457 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 )
370476 end
371477 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
373481 end
374482 end
375483
0 commit comments