Skip to content

Commit 7428bfa

Browse files
committed
feat(terminal): add native terminal fallback and improve configuration
Change-Id: Ic9a443a3c8f822cf42c361d43a8b4667998d2ca9 Signed-off-by: Thomas Kosiewski <[email protected]>
1 parent ba1698c commit 7428bfa

File tree

6 files changed

+327
-135
lines changed

6 files changed

+327
-135
lines changed

CLAUDE.md

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,8 @@ Claude Code Neovim Integration is a Neovim plugin that enables bidirectional com
1212
# Format code with StyLua
1313
make format
1414

15-
# Check code for errors
1615
make check # Runs luacheck
17-
18-
# Run all tests
1916
make test # Runs all tests with busted
20-
2117
# Run specific test file
2218
nvim --headless -u tests/minimal_init.lua -c "lua require('tests.unit.config_spec')"
2319
```
@@ -133,7 +129,7 @@ require("claudecode").setup({
133129
port_range = { min = 10000, max = 65535 },
134130

135131
-- Auto-start WebSocket server on Neovim startup
136-
auto_start = false,
132+
auto_start = true,
137133

138134
-- Custom terminal command to use when launching Claude
139135
terminal_cmd = nil, -- e.g., "toggleterm"

README.md

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,18 @@ A Neovim plugin that integrates with Claude Code CLI to provide a seamless AI co
1212
- 🔍 Selection tracking to provide context to Claude
1313
- 🛠️ Integration with Neovim's buffer and window management
1414
- 📝 Support for file operations and diagnostics
15-
- 🖥️ Interactive vertical split terminal for Claude sessions (via `folke/snacks.nvim`)
15+
- 🖥️ Interactive vertical split terminal for Claude sessions (supports `folke/snacks.nvim` or native Neovim terminal)
1616
- 🔒 Automatic cleanup on exit - server shutdown and lockfile removal
1717

1818
## Requirements
1919

2020
- Neovim >= 0.8.0
2121
- Claude Code CLI installed and in your PATH
2222
- Lua >= 5.1
23-
- **Required for terminal integration:** [folke/snacks.nvim](https://github.com/folke/snacks.nvim) - Terminal management plugin
23+
- **Optional for terminal integration:** [folke/snacks.nvim](https://github.com/folke/snacks.nvim) - Terminal management plugin (can use native Neovim terminal as an alternative).
2424
- Optional: plenary.nvim for additional utilities
2525

26-
Note: The terminal feature requires Snacks.nvim to be installed and available. If not available, the terminal commands will display an error message, but the core Claude Code integration will still function.
26+
Note: The terminal feature can use `Snacks.nvim` or the native Neovim terminal. If `Snacks.nvim` is configured as the provider but is not available, it will fall back to the native terminal.
2727

2828
## Installation
2929

@@ -84,15 +84,16 @@ return {
8484
terminal = {
8585
split_side = "left", -- "left" or "right"
8686
split_width_percentage = 0.4, -- 0.0 to 1.0
87+
provider = "snacks", -- "snacks" or "native" (defaults to "snacks")
88+
show_native_term_exit_tip = true, -- Show tip for Ctrl-\\ Ctrl-N (defaults to true)
8789
},
8890
},
8991
-- The main require("claudecode").setup(opts) will handle passing
9092
-- opts.terminal to the terminal module's setup.
9193
config = true, -- or function(_, opts) require("claudecode").setup(opts) end
9294
keys = {
93-
{ "<leader>cc", "<cmd>ClaudeCodeStart<cr>", desc = "Start Claude Code" },
95+
{ "<leader>cc", "<cmd>ClaudeCode<cr>", desc = "Toggle Claude Terminal" },
9496
{ "<leader>cs", "<cmd>ClaudeCodeSend<cr>", desc = "Send to Claude Code" },
95-
{ "<leader>ct", "<cmd>ClaudeCode<cr>", desc = "Toggle Claude Terminal" },
9697
{ "<leader>co", "<cmd>ClaudeCodeOpen<cr>", desc = "Open Claude Terminal" },
9798
{ "<leader>cx", "<cmd>ClaudeCodeClose<cr>", desc = "Close Claude Terminal" },
9899
},
@@ -117,19 +118,20 @@ return {
117118
opts = {
118119
-- Development configuration for claudecode main
119120
log_level = "debug",
120-
auto_start = true, -- Optional: auto-start the server
121+
auto_start = true,
121122

122123
-- Example terminal configuration for dev:
123124
terminal = {
124125
split_side = "right",
125126
split_width_percentage = 0.25,
127+
provider = "native",
128+
show_native_term_exit_tip = false,
126129
},
127130
},
128131
config = true,
129132
keys = {
130-
{ "<leader>cc", "<cmd>ClaudeCodeStart<cr>", desc = "Start Claude Code" },
133+
{ "<leader>cc", "<cmd>ClaudeCode<cr>", desc = "Toggle Claude Terminal" },
131134
{ "<leader>cs", "<cmd>ClaudeCodeSend<cr>", desc = "Send to Claude Code" },
132-
{ "<leader>ct", "<cmd>ClaudeCode<cr>", desc = "Toggle Claude Terminal" },
133135
{ "<leader>co", "<cmd>ClaudeCodeOpen<cr>", desc = "Open Claude Terminal" },
134136
{ "<leader>cx", "<cmd>ClaudeCodeClose<cr>", desc = "Close Claude Terminal" },
135137
},
@@ -151,8 +153,9 @@ require("claudecode").setup({
151153
-- Port range for WebSocket server (default: 10000-65535)
152154
port_range = { min = 10000, max = 65535 },
153155

154-
-- Auto-start WebSocket server on Neovim startup
155-
auto_start = false,
156+
-- Auto-start WebSocket server when the plugin is loaded.
157+
-- Note: With lazy-loading (e.g., LazyVim), this means the server starts when a plugin command is first used.
158+
auto_start = true,
156159

157160
-- Custom terminal command to use when launching Claude
158161
-- This command is used by the new interactive terminal feature.
@@ -172,6 +175,13 @@ require("claudecode").setup({
172175

173176
-- Width of the terminal as a percentage of total editor width (0.0 to 1.0)
174177
split_width_percentage = 0.30, -- Default
178+
179+
-- Terminal provider ('snacks' or 'native')
180+
-- If 'snacks' is chosen but not available, it will fall back to 'native'.
181+
provider = "snacks", -- Default
182+
183+
-- Whether to show a one-time tip about exiting native terminal mode (Ctrl-\\ Ctrl-N)
184+
show_native_term_exit_tip = true -- Default
175185
}
176186
})
177187
```
@@ -209,12 +219,12 @@ require("claudecode").setup({
209219
No default keymaps are provided. Add your own in your configuration:
210220

211221
```lua
212-
vim.keymap.set("n", "<leader>cc", "<cmd>ClaudeCodeStart<cr>", { desc = "Start Claude Code" })
222+
vim.keymap.set("n", "<leader>cc", "<cmd>ClaudeCode<cr>", { desc = "Toggle Claude Terminal" })
213223
vim.keymap.set({"n", "v"}, "<leader>cs", "<cmd>ClaudeCodeSend<cr>", { desc = "Send to Claude Code" })
214-
+vim.keymap.set("n", "<leader>ct", "<cmd>ClaudeCode<cr>", { desc = "Toggle Claude Terminal" })
215-
+-- Or more specific maps:
216-
+-- vim.keymap.set("n", "<leader>co", "<cmd>ClaudeCodeOpen<cr>", { desc = "Open Claude Terminal" })
217-
+-- vim.keymap.set("n", "<leader>cx", "<cmd>ClaudeCodeClose<cr>", { desc = "Close Claude Terminal" })
224+
225+
-- Or more specific maps:
226+
vim.keymap.set("n", "<leader>co", "<cmd>ClaudeCodeOpen<cr>", { desc = "Open Claude Terminal" })
227+
vim.keymap.set("n", "<leader>cx", "<cmd>ClaudeCodeClose<cr>", { desc = "Close Claude Terminal" })
218228
```
219229

220230
## Architecture

lua/claudecode/config.lua

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,21 @@
1-
-- Configuration management for Claude Code Neovim integration
1+
--- Manages configuration for the Claude Code Neovim integration.
2+
-- Provides default settings, validation, and application of user-defined configurations.
23
local M = {}
34

4-
-- Default configuration
55
M.defaults = {
6-
-- Port range for WebSocket server
76
port_range = { min = 10000, max = 65535 },
8-
9-
-- Auto-start WebSocket server on Neovim startup
10-
auto_start = false,
11-
12-
-- Custom terminal command to use when launching Claude
7+
auto_start = true,
138
terminal_cmd = nil,
14-
15-
-- Log level (trace, debug, info, warn, error)
169
log_level = "info",
17-
18-
-- Enable sending selection updates to Claude
1910
track_selection = true,
2011
}
2112

22-
-- Validate configuration
13+
--- Validates the provided configuration table.
14+
-- Ensures that all configuration options are of the correct type and within valid ranges.
15+
-- @param config table The configuration table to validate.
16+
-- @return boolean true if the configuration is valid.
17+
-- @error string if any configuration option is invalid.
2318
function M.validate(config)
24-
-- Validate port range
2519
assert(
2620
type(config.port_range) == "table"
2721
and type(config.port_range.min) == "number"
@@ -32,13 +26,10 @@ function M.validate(config)
3226
"Invalid port range"
3327
)
3428

35-
-- Validate auto_start
3629
assert(type(config.auto_start) == "boolean", "auto_start must be a boolean")
3730

38-
-- Validate terminal_cmd
3931
assert(config.terminal_cmd == nil or type(config.terminal_cmd) == "string", "terminal_cmd must be nil or a string")
4032

41-
-- Validate log_level
4233
local valid_log_levels = { "trace", "debug", "info", "warn", "error" }
4334
local is_valid_log_level = false
4435
for _, level in ipairs(valid_log_levels) do
@@ -49,21 +40,23 @@ function M.validate(config)
4940
end
5041
assert(is_valid_log_level, "log_level must be one of: " .. table.concat(valid_log_levels, ", "))
5142

52-
-- Validate track_selection
5343
assert(type(config.track_selection) == "boolean", "track_selection must be a boolean")
5444

5545
return true
5646
end
5747

58-
-- Apply configuration with validation
48+
--- Applies user configuration on top of default settings and validates the result.
49+
-- Merges the user-provided configuration with the default configuration,
50+
-- then validates the merged configuration.
51+
-- @param user_config table|nil The user-provided configuration table.
52+
-- @return table The final, validated configuration table.
5953
function M.apply(user_config)
6054
local config = vim.deepcopy(M.defaults)
6155

6256
if user_config then
6357
config = vim.tbl_deep_extend("force", config, user_config)
6458
end
6559

66-
-- Validate the merged configuration
6760
M.validate(config)
6861

6962
return config

lua/claudecode/init.lua

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,10 @@ M.version = {
3737
--- @field log_level "trace"|"debug"|"info"|"warn"|"error" Log level.
3838
--- @field track_selection boolean Enable sending selection updates to Claude.
3939

40-
-- Default configuration
4140
--- @type ClaudeCode.Config
4241
local default_config = {
4342
port_range = { min = 10000, max = 65535 },
44-
auto_start = false,
43+
auto_start = true,
4544
terminal_cmd = nil,
4645
log_level = "info",
4746
track_selection = true,
@@ -53,7 +52,6 @@ local default_config = {
5352
--- @field port number|nil The port the server is running on.
5453
--- @field initialized boolean Whether the plugin has been initialized.
5554

56-
-- Plugin state
5755
--- @type ClaudeCode.State
5856
M.state = {
5957
config = vim.deepcopy(default_config),
@@ -63,7 +61,12 @@ M.state = {
6361
}
6462

6563
--- Set up the plugin with user configuration
66-
---@param opts table|nil Optional configuration table to override defaults
64+
---@param opts table|nil Optional configuration table to override defaults.
65+
---@field opts.terminal table|nil Configuration for the terminal module.
66+
---@field opts.terminal.split_side string|nil 'left' or 'right'.
67+
---@field opts.terminal.split_width_percentage number|nil Percentage of screen width (0.0 to 1.0).
68+
---@field opts.terminal.provider string|nil 'snacks' or 'native'.
69+
---@field opts.terminal.show_native_term_exit_tip boolean|nil Show tip for exiting native terminal (default: true).
6770
---@return table The plugin module
6871
function M.setup(opts)
6972
opts = opts or {}

0 commit comments

Comments
 (0)