@@ -16,6 +16,10 @@ local defaults = {
1616 auto_close = true ,
1717 env = {},
1818 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
1923}
2024
2125M .defaults = defaults
@@ -172,18 +176,67 @@ local function build_config(opts_override)
172176 snacks_win_opts = function (val )
173177 return type (val ) == " table"
174178 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 ,
175196 }
176197 for key , val in pairs (opts_override ) do
177198 if effective_config [key ] ~= nil and validators [key ] and validators [key ](val ) then
178199 effective_config [key ] = val
179200 end
180201 end
181202 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+
182234 return {
183235 split_side = effective_config .split_side ,
184236 split_width_percentage = effective_config .split_width_percentage ,
185237 auto_close = effective_config .auto_close ,
186238 snacks_win_opts = effective_config .snacks_win_opts ,
239+ cwd = resolved_cwd ,
187240 }
188241end
189242
@@ -300,24 +353,84 @@ function M.setup(user_term_config, p_terminal_cmd, p_env)
300353 end
301354
302355 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
316374 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 )
318433 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 )
321434 end
322435 end
323436
0 commit comments