@@ -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
@@ -191,18 +195,67 @@ local function build_config(opts_override)
191195 snacks_win_opts = function (val )
192196 return type (val ) == " table"
193197 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 ,
194215 }
195216 for key , val in pairs (opts_override ) do
196217 if effective_config [key ] ~= nil and validators [key ] and validators [key ](val ) then
197218 effective_config [key ] = val
198219 end
199220 end
200221 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+
201253 return {
202254 split_side = effective_config .split_side ,
203255 split_width_percentage = effective_config .split_width_percentage ,
204256 auto_close = effective_config .auto_close ,
205257 snacks_win_opts = effective_config .snacks_win_opts ,
258+ cwd = resolved_cwd ,
206259 }
207260end
208261
@@ -319,9 +372,30 @@ function M.setup(user_term_config, p_terminal_cmd, p_env)
319372 end
320373
321374 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
325399 elseif k == " provider_opts" then
326400 -- Handle nested provider options
327401 if type (v ) == " table" then
@@ -344,26 +418,60 @@ function M.setup(user_term_config, p_terminal_cmd, p_env)
344418 else
345419 vim .notify (" claudecode.terminal.setup: Invalid value for provider_opts: " .. tostring (v ), vim .log .levels .WARN )
346420 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
362451 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 )
364470 end
365471 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
367475 end
368476 end
369477
0 commit comments