-
Notifications
You must be signed in to change notification settings - Fork 91
Description
Problem / Use Case
Currently, claudecode.nvim only supports a single terminal layout configuration. Users who want to interact with Claude Code in different contexts (e.g., floating window for quick queries, side split for longer sessions) must either:
- Reconfigure and reload the plugin to change layouts
- Create multiple independent Claude instances (which breaks the single conversation flow)
- Manually manipulate windows after opening
This limitation makes it difficult to have flexible workflow patterns while maintaining a single Claude conversation instance.
Proposed Solution
Support multiple named terminal layout configurations accessible via Lua API, allowing layout selection to be completely separate from Claude CLI arguments.
Configuration Example
{
"coder/claudecode.nvim",
opts = {
terminal = {
-- Define multiple named configurations
configurations = {
float = {
snacks_win_opts = {
position = "float",
width = 0.8,
height = 0.8,
border = "rounded",
}
},
split = {
snacks_win_opts = {
position = "right",
width = 0.4,
border = "rounded",
}
},
drawer = {
snacks_win_opts = {
position = "bottom",
height = 0.3,
border = "single",
}
}
},
-- Optional: specify default configuration
default = "float" -- used when no layout is specified
},
},
}Lua API Usage
-- Open Claude with specific layout and arguments
require("claudecode").open({
layout = "split",
args = "--dangerously-skip-permissions --continue"
})
-- Or just layout (uses default args)
require("claudecode").open({ layout = "float" })
-- Or just args (uses default layout)
require("claudecode").open({ args = "--continue" })
-- Focus with layout preference (switch to different layout)
require("claudecode").focus({ layout = "drawer" })Keymap Examples
-- Floating window for quick access
vim.keymap.set({ "n", "i", "v", "t" }, "<C-M-S-a>", function()
require("claudecode").open({
layout = "float",
args = "--dangerously-skip-permissions --continue"
})
end, { desc = "Claude (floating)" })
-- Split for focused work
vim.keymap.set({ "n", "i", "v", "t" }, "<C-M-S-s>", function()
require("claudecode").open({
layout = "split",
args = "--dangerously-skip-permissions --continue"
})
end, { desc = "Claude (split)" })
-- Drawer for context checking
vim.keymap.set("n", "<leader>ad", function()
require("claudecode").open({
layout = "drawer",
args = "--continue"
})
end, { desc = "Claude (drawer)" })Command Compatibility
The existing :ClaudeCode command should continue to work unchanged, using the default layout:
" Uses default layout configuration
:ClaudeCode --continue
:ClaudeCode --dangerously-skip-permissionsBenefits
- Single Instance: All layouts reference the same Claude conversation and WebSocket server
- Declarative: Layout configurations defined once, reused everywhere
- No CLI Conflicts: Layout selection completely separate from Claude CLI arguments
- Flexible Workflows: Different layouts for different contexts without reconfiguration
- Backward Compatible: Existing configurations continue to work
- Clean API: Simple, predictable Lua interface
- Composable: Easy to build complex keymaps and commands on top
Backward Compatibility
For backward compatibility, both configuration styles should be supported:
-- Old style (still works, becomes the default configuration)
terminal = {
snacks_win_opts = { position = "float", ... }
}
-- New style (opt-in for multiple configurations)
terminal = {
configurations = {
float = { snacks_win_opts = { ... } },
split = { snacks_win_opts = { ... } }
},
default = "float"
}If configurations is not specified, the plugin behaves exactly as it does today.
Implementation Notes
- The same Claude CLI process and WebSocket server instance should be reused across all layouts
- When switching layouts, the terminal buffer could be moved to a new window with the requested layout
- The
layoutparameter should be optional; if omitted, use thedefaultconfiguration - Invalid layout names should fall back to the default configuration with a warning
Alternative Considered
Using command-line arguments like :ClaudeCode split --continue was considered but rejected because it would conflict with Claude CLI's native argument parsing and create an antipattern of mixing layout concerns with CLI flags.