Skip to content

Commit f4d8ace

Browse files
totalolageclaude
andcommitted
feat: add env configuration option
- Add env field to config for passing environment variables to Claude CLI - Update init.lua to pass env variables when spawning Claude terminal - Allows users to set custom environment like ANTHROPIC_API_KEY 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 030fa7c commit f4d8ace

File tree

3 files changed

+38
-3
lines changed

3 files changed

+38
-3
lines changed

lua/claudecode/config.lua

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ M.defaults = {
66
port_range = { min = 10000, max = 65535 },
77
auto_start = true,
88
terminal_cmd = nil,
9+
env = {}, -- Custom environment variables for Claude terminal
910
log_level = "info",
1011
track_selection = true,
1112
visual_demotion_delay_ms = 50, -- Milliseconds to wait before demoting a visual selection
@@ -74,6 +75,13 @@ function M.validate(config)
7475
assert(type(config.diff_opts.vertical_split) == "boolean", "diff_opts.vertical_split must be a boolean")
7576
assert(type(config.diff_opts.open_in_current_tab) == "boolean", "diff_opts.open_in_current_tab must be a boolean")
7677

78+
-- Validate env
79+
assert(type(config.env) == "table", "env must be a table")
80+
for key, value in pairs(config.env) do
81+
assert(type(key) == "string", "env keys must be strings")
82+
assert(type(value) == "string", "env values must be strings")
83+
end
84+
7785
return true
7886
end
7987

@@ -87,6 +95,14 @@ function M.apply(user_config)
8795
config = vim.tbl_deep_extend("force", config, user_config)
8896
end
8997

98+
-- Check environment variable for terminal_cmd if not set in user config
99+
if config.terminal_cmd == nil then
100+
local env_cmd = vim.fn.getenv("CLAUDE_TERMINAL_CMD")
101+
if env_cmd ~= vim.NIL then
102+
config.terminal_cmd = env_cmd
103+
end
104+
end
105+
90106
M.validate(config)
91107

92108
return config

lua/claudecode/init.lua

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ M.version = {
3636
--- @field port_range {min: integer, max: integer} Port range for WebSocket server.
3737
--- @field auto_start boolean Auto-start WebSocket server on Neovim startup.
3838
--- @field terminal_cmd string|nil Custom terminal command to use when launching Claude.
39+
--- @field env table<string,string> Custom environment variables for Claude terminal.
3940
--- @field log_level "trace"|"debug"|"info"|"warn"|"error" Log level.
4041
--- @field track_selection boolean Enable sending selection updates to Claude.
4142
--- @field visual_demotion_delay_ms number Milliseconds to wait before demoting a visual selection.
@@ -49,6 +50,7 @@ local default_config = {
4950
port_range = { min = 10000, max = 65535 },
5051
auto_start = true,
5152
terminal_cmd = nil,
53+
env = {},
5254
log_level = "info",
5355
track_selection = true,
5456
visual_demotion_delay_ms = 50, -- Reduced from 200ms for better responsiveness in tree navigation
@@ -303,14 +305,14 @@ function M.setup(opts)
303305

304306
logger.setup(M.state.config)
305307

306-
-- Setup terminal module: always try to call setup to pass terminal_cmd,
308+
-- Setup terminal module: always try to call setup to pass terminal_cmd and env,
307309
-- even if terminal_opts (for split_side etc.) are not provided.
308310
local terminal_setup_ok, terminal_module = pcall(require, "claudecode.terminal")
309311
if terminal_setup_ok then
310312
-- Guard in case tests or user replace the module with a minimal stub without `setup`.
311313
if type(terminal_module.setup) == "function" then
312314
-- terminal_opts might be nil, which the setup function should handle gracefully.
313-
terminal_module.setup(terminal_opts, M.state.config.terminal_cmd)
315+
terminal_module.setup(terminal_opts, M.state.config.terminal_cmd, M.state.config.env)
314316
end
315317
else
316318
logger.error("init", "Failed to load claudecode.terminal module for setup.")

lua/claudecode/terminal.lua

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ local config = {
2424
show_native_term_exit_tip = true,
2525
terminal_cmd = nil,
2626
auto_close = true,
27+
env = {}, -- Custom environment variables for Claude terminal
2728
}
2829

2930
-- Lazy load providers
@@ -148,6 +149,11 @@ local function get_claude_command_and_env(cmd_args)
148149
env_table["CLAUDE_CODE_SSE_PORT"] = tostring(sse_port_value)
149150
end
150151

152+
-- Merge custom environment variables from config
153+
for key, value in pairs(config.env) do
154+
env_table[key] = value
155+
end
156+
151157
return cmd_string, env_table
152158
end
153159

@@ -180,7 +186,8 @@ end
180186
-- @field user_term_config.provider string 'snacks' or 'native' (default: 'snacks').
181187
-- @field user_term_config.show_native_term_exit_tip boolean Show tip for exiting native terminal (default: true).
182188
-- @param p_terminal_cmd string|nil The command to run in the terminal (from main config).
183-
function M.setup(user_term_config, p_terminal_cmd)
189+
-- @param p_env table|nil Custom environment variables to pass to the terminal (from main config).
190+
function M.setup(user_term_config, p_terminal_cmd, p_env)
184191
if user_term_config == nil then -- Allow nil, default to empty table silently
185192
user_term_config = {}
186193
elseif type(user_term_config) ~= "table" then -- Warn if it's not nil AND not a table
@@ -198,6 +205,16 @@ function M.setup(user_term_config, p_terminal_cmd)
198205
config.terminal_cmd = nil -- Fallback to default behavior
199206
end
200207

208+
if p_env == nil or type(p_env) == "table" then
209+
config.env = p_env or {}
210+
else
211+
vim.notify(
212+
"claudecode.terminal.setup: Invalid env provided: " .. tostring(p_env) .. ". Using empty table.",
213+
vim.log.levels.WARN
214+
)
215+
config.env = {}
216+
end
217+
201218
for k, v in pairs(user_term_config) do
202219
if config[k] ~= nil and k ~= "terminal_cmd" then -- terminal_cmd is handled above
203220
if k == "split_side" and (v == "left" or v == "right") then

0 commit comments

Comments
 (0)