Skip to content

feat: add env configuration option #21

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions lua/claudecode/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ M.defaults = {
port_range = { min = 10000, max = 65535 },
auto_start = true,
terminal_cmd = nil,
env = {}, -- Custom environment variables for Claude terminal
log_level = "info",
track_selection = true,
visual_demotion_delay_ms = 50, -- Milliseconds to wait before demoting a visual selection
Expand Down Expand Up @@ -61,6 +62,13 @@ function M.validate(config)
assert(type(config.diff_opts.vertical_split) == "boolean", "diff_opts.vertical_split must be a boolean")
assert(type(config.diff_opts.open_in_current_tab) == "boolean", "diff_opts.open_in_current_tab must be a boolean")

-- Validate env
assert(type(config.env) == "table", "env must be a table")
for key, value in pairs(config.env) do
assert(type(key) == "string", "env keys must be strings")
assert(type(value) == "string", "env values must be strings")
end

return true
end

Expand All @@ -76,9 +84,19 @@ function M.apply(user_config)
config = vim.tbl_deep_extend("force", config, user_config)
end

-- Check environment variable for terminal_cmd if not set in user config
if config.terminal_cmd == nil then
local env_cmd = vim.fn.getenv("CLAUDE_TERMINAL_CMD")
if env_cmd ~= vim.NIL then
config.terminal_cmd = env_cmd
end
end
Comment on lines +87 to +93
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would rather have the user configure that in their settings and then pass that value into the terminal_cmd instead of us doing it here.


M.validate(config)

return config
end

return M


Comment on lines +101 to +102
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these should be removed if you run nix fmt

8 changes: 6 additions & 2 deletions lua/claudecode/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ M.version = {
--- @field port_range {min: integer, max: integer} Port range for WebSocket server.
--- @field auto_start boolean Auto-start WebSocket server on Neovim startup.
--- @field terminal_cmd string|nil Custom terminal command to use when launching Claude.
--- @field env table<string,string> Custom environment variables for Claude terminal.
--- @field log_level "trace"|"debug"|"info"|"warn"|"error" Log level.
--- @field track_selection boolean Enable sending selection updates to Claude.
--- @field visual_demotion_delay_ms number Milliseconds to wait before demoting a visual selection.
Expand All @@ -44,6 +45,7 @@ local default_config = {
port_range = { min = 10000, max = 65535 },
auto_start = true,
terminal_cmd = nil,
env = {},
log_level = "info",
track_selection = true,
visual_demotion_delay_ms = 200,
Expand Down Expand Up @@ -97,14 +99,14 @@ function M.setup(opts)
local logger = require("claudecode.logger")
logger.setup(M.state.config)

-- Setup terminal module: always try to call setup to pass terminal_cmd,
-- Setup terminal module: always try to call setup to pass terminal_cmd and env,
-- even if terminal_opts (for split_side etc.) are not provided.
local terminal_setup_ok, terminal_module = pcall(require, "claudecode.terminal")
if terminal_setup_ok then
-- terminal_opts might be nil if user only configured top-level terminal_cmd
-- and not specific terminal appearance options.
-- The terminal.setup function handles nil for its first argument.
terminal_module.setup(terminal_opts, M.state.config.terminal_cmd)
terminal_module.setup(terminal_opts, M.state.config.terminal_cmd, M.state.config.env)
else
logger.error("init", "Failed to load claudecode.terminal module for setup.")
end
Expand Down Expand Up @@ -338,3 +340,5 @@ function M.get_version()
end

return M


19 changes: 18 additions & 1 deletion lua/claudecode/terminal.lua
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ local term_module_config = {
provider = "snacks",
show_native_term_exit_tip = true,
terminal_cmd = nil, -- Will be set by setup() from main config
env = {}, -- Will be set by setup() from main config
}

--- State to keep track of the managed Claude terminal instance (from Snacks).
Expand Down Expand Up @@ -53,7 +54,8 @@ end
-- @field user_term_config.provider string 'snacks' or 'native' (default: 'snacks').
-- @field user_term_config.show_native_term_exit_tip boolean Show tip for exiting native terminal (default: true).
-- @param p_terminal_cmd string|nil The command to run in the terminal (from main config).
function M.setup(user_term_config, p_terminal_cmd)
-- @param p_env table|nil Custom environment variables to pass to the terminal (from main config).
function M.setup(user_term_config, p_terminal_cmd, p_env)
if user_term_config == nil then -- Allow nil, default to empty table silently
user_term_config = {}
elseif type(user_term_config) ~= "table" then -- Warn if it's not nil AND not a table
Expand All @@ -71,6 +73,16 @@ function M.setup(user_term_config, p_terminal_cmd)
term_module_config.terminal_cmd = nil -- Fallback to default behavior in get_claude_command
end

if p_env == nil or type(p_env) == "table" then
term_module_config.env = p_env or {}
else
vim.notify(
"claudecode.terminal.setup: Invalid env provided: " .. tostring(p_env) .. ". Using empty table.",
vim.log.levels.WARN
)
term_module_config.env = {}
end

for k, v in pairs(user_term_config) do
if term_module_config[k] ~= nil and k ~= "terminal_cmd" then -- terminal_cmd is handled above
if k == "split_side" and (v == "left" or v == "right") then
Expand Down Expand Up @@ -351,6 +363,11 @@ local function get_claude_command_and_env()
env_table["CLAUDE_CODE_SSE_PORT"] = tostring(sse_port_value)
end

-- Merge custom environment variables from config
for key, value in pairs(term_module_config.env) do
env_table[key] = value
end

return cmd_string, env_table
end

Expand Down
Loading