diff --git a/README.md b/README.md index 36fc78b..c3ff50c 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,12 @@ require("claude-code").setup({ git = { use_git_root = true, -- Set CWD to git root when opening Claude Code (if in git project) }, + -- Shell-specific settings + shell = { + separator = '&&', -- Command separator used in shell commands + pushd_cmd = 'pushd', -- Command to push directory onto stack (e.g., 'pushd' for bash/zsh, 'enter' for nushell) + popd_cmd = 'popd', -- Command to pop directory from stack (e.g., 'popd' for bash/zsh, 'exit' for nushell) + }, -- Command settings command = "claude", -- Command used to launch Claude Code -- Command variants diff --git a/lua/claude-code/config.lua b/lua/claude-code/config.lua index ab1d618..e1c99a8 100644 --- a/lua/claude-code/config.lua +++ b/lua/claude-code/config.lua @@ -47,11 +47,18 @@ local M = {} -- @field verbose string|boolean Enable verbose logging with full turn-by-turn output -- Additional options can be added as needed +--- ClaudeCodeShell class for shell configuration +-- @table ClaudeCodeShell +-- @field separator string Command separator used in shell commands (e.g., '&&', ';', '|') +-- @field pushd_cmd string Command to push directory onto stack (e.g., 'pushd' for bash/zsh) +-- @field popd_cmd string Command to pop directory from stack (e.g., 'popd' for bash/zsh) + --- ClaudeCodeConfig class for main configuration -- @table ClaudeCodeConfig -- @field window ClaudeCodeWindow Terminal window settings -- @field refresh ClaudeCodeRefresh File refresh settings -- @field git ClaudeCodeGit Git integration settings +-- @field shell ClaudeCodeShell Shell-specific configuration -- @field command string Command used to launch Claude Code -- @field command_variants ClaudeCodeCommandVariants Command variants configuration -- @field keymaps ClaudeCodeKeymaps Keymaps configuration @@ -81,6 +88,12 @@ M.default_config = { use_git_root = true, -- Set CWD to git root when opening Claude Code (if in git project) multi_instance = true, -- Use multiple Claude instances (one per git root) }, + -- Shell-specific settings + shell = { + separator = '&&', -- Command separator used in shell commands + pushd_cmd = 'pushd', -- Command to push directory onto stack + popd_cmd = 'popd', -- Command to pop directory from stack + }, -- Command settings command = 'claude', -- Command used to launch Claude Code -- Command variants @@ -179,6 +192,23 @@ local function validate_config(config) return false, 'git.multi_instance must be a boolean' end + -- Validate shell settings + if type(config.shell) ~= 'table' then + return false, 'shell config must be a table' + end + + if type(config.shell.separator) ~= 'string' then + return false, 'shell.separator must be a string' + end + + if type(config.shell.pushd_cmd) ~= 'string' then + return false, 'shell.pushd_cmd must be a string' + end + + if type(config.shell.popd_cmd) ~= 'string' then + return false, 'shell.popd_cmd must be a string' + end + -- Validate command settings if type(config.command) ~= 'string' then return false, 'command must be a string' diff --git a/lua/claude-code/terminal.lua b/lua/claude-code/terminal.lua index 6adaf16..2b8172d 100644 --- a/lua/claude-code/terminal.lua +++ b/lua/claude-code/terminal.lua @@ -149,7 +149,10 @@ function M.toggle(claude_code, config, git) local git_root = git.get_git_root() if git_root then -- Use pushd/popd to change directory instead of --cwd - cmd = 'terminal pushd ' .. git_root .. ' && ' .. config.command .. ' && popd' + local separator = config.shell.separator + local pushd_cmd = config.shell.pushd_cmd + local popd_cmd = config.shell.popd_cmd + cmd = 'terminal ' .. pushd_cmd .. ' ' .. git_root .. ' ' .. separator .. ' ' .. config.command .. ' ' .. separator .. ' ' .. popd_cmd end end diff --git a/tests/spec/terminal_spec.lua b/tests/spec/terminal_spec.lua index d861c4a..bd5b5fd 100644 --- a/tests/spec/terminal_spec.lua +++ b/tests/spec/terminal_spec.lua @@ -85,6 +85,11 @@ describe('terminal module', function() use_git_root = true, multi_instance = true, }, + shell = { + separator = '&&', + pushd_cmd = 'pushd', + popd_cmd = 'popd', + }, } claude_code = { @@ -300,6 +305,30 @@ describe('terminal module', function() assert.is_true(git_root_cmd_found, 'Terminal command should include git root') end) + + it('should use custom pushd/popd commands when configured', function() + -- Set git config to use root + config.git.use_git_root = true + -- Configure custom directory commands for nushell + config.shell.pushd_cmd = 'enter' + config.shell.popd_cmd = 'exit' + config.shell.separator = ';' + + -- Call toggle + terminal.toggle(claude_code, config, git) + + -- Check that custom commands were used in terminal command + local custom_cmd_found = false + + for _, cmd in ipairs(vim_cmd_calls) do + if cmd:match('terminal enter /test/git/root ; ' .. config.command .. ' ; exit') then + custom_cmd_found = true + break + end + end + + assert.is_true(custom_cmd_found, 'Terminal command should use custom directory commands') + end) end) describe('start_in_normal_mode option', function()