Claude Code is a terminal application — which makes it a natural fit for Vim and Neovim development workflows. Unlike IDE-based AI tools that require plugins and GUI integration, Claude Code runs alongside your editor in an adjacent terminal pane: the same environment where you run tests, manage git, and execute build commands.
This guide covers Claude Code with Vim/Neovim: terminal multiplexer setup, efficient pane switching, shell integration, and patterns that make the combination more productive than either tool alone.
Terminal Multiplexer Setup
The most effective Claude Code + Vim workflow uses a terminal multiplexer (tmux or Zellij) to keep both visible simultaneously.
tmux Configuration
Set up tmux for Vim + Claude Code development.
I want: left pane for Vim, right pane for Claude Code.
Keyboard shortcuts to move between them without the mouse.
# ~/.tmux.conf
set -g prefix C-a # Ctrl+A prefix (easier than Ctrl+B for many)
unbind C-b
# Split panes
bind | split-window -h -c "#{pane_current_path}" # Ctrl+A | for vertical split
bind - split-window -v -c "#{pane_current_path}" # Ctrl+A - for horizontal split
# Navigate panes with Alt+Arrow (no prefix needed)
bind -n M-Left select-pane -L
bind -n M-Right select-pane -R
bind -n M-Up select-pane -U
bind -n M-Down select-pane -D
# Resize panes
bind -r H resize-pane -L 5
bind -r L resize-pane -R 5
# True color support for Neovim
set -g default-terminal "tmux-256color"
set -ag terminal-overrides ",xterm-256color:RGB"
# Mouse support (optional — useful for pane resizing)
set -g mouse on
# Larger scrollback
set -g history-limit 50000
Start a Claude Code session in a layout:
# Launch script: dev-session.sh
#!/bin/bash
SESSION="dev"
PROJECT=${1:-$(pwd)}
tmux new-session -d -s $SESSION -c "$PROJECT"
tmux rename-window -t $SESSION:0 "editor"
# Left pane: Neovim
tmux send-keys -t $SESSION:0 "nvim ." Enter
# Right pane (30% width): Claude Code
tmux split-window -h -p 35 -c "$PROJECT"
tmux send-keys -t $SESSION:0.right "claude" Enter
tmux attach -t $SESSION
alias dev='~/.local/bin/dev-session.sh'
# Now: `dev ~/projects/myapp` opens Neovim + Claude Code side by side
Neovim Integration via Terminal
Claude Code runs in the Neovim built-in terminal (:term):
" ~/.config/nvim/lua/claude.lua
local M = {}
-- Open Claude Code in a vertical split terminal
function M.open()
vim.cmd('vsplit | terminal claude')
-- Enter insert mode in the terminal
vim.cmd('startinsert')
end
-- Open in a horizontal split at bottom
function M.open_bottom()
vim.cmd('split | terminal claude')
vim.cmd('resize 20')
vim.cmd('startinsert')
end
-- Keybindings
vim.keymap.set('n', '<leader>cc', M.open, { desc = 'Open Claude Code' })
vim.keymap.set('n', '<leader>cb', M.open_bottom, { desc = 'Open Claude Code (bottom)' })
-- Navigate out of terminal back to Neovim with Escape
vim.keymap.set('t', '<Esc>', [[<C-\><C-n>]], { noremap = true })
-- Navigate between panes from terminal mode
vim.keymap.set('t', '<C-h>', [[<C-\><C-n><C-w>h]])
vim.keymap.set('t', '<C-j>', [[<C-\><C-n><C-w>j]])
vim.keymap.set('t', '<C-k>', [[<C-\><C-n><C-w>k]])
vim.keymap.set('t', '<C-l>', [[<C-\><C-n><C-w>l]])
return M
-- In init.lua
require('claude')
Now <leader>cc opens Claude Code in a Neovim side panel. Escape exits terminal mode (returns to Normal mode for Neovim navigation). Ctrl+h/j/k/l switches between panes without leaving terminal insert mode.
Sending Text to Claude Code
A workflow where you select code in Vim and send it to Claude Code:
-- Send visual selection to Claude Code terminal pane
function M.send_selection()
-- Get visual selection
local start_line = vim.fn.getpos("'<")[2]
local end_line = vim.fn.getpos("'>")[2]
local lines = vim.fn.getline(start_line, end_line)
local text = table.concat(lines, '\n')
-- Find the Claude terminal buffer
for _, buf in ipairs(vim.api.nvim_list_bufs()) do
local bufname = vim.api.nvim_buf_get_name(buf)
if bufname:match('term://.*claude') then
-- Send text to terminal
local chan = vim.api.nvim_buf_get_option(buf, 'channel')
vim.api.nvim_chan_send(chan, 'Explain this code:\n```\n' .. text .. '\n```\n')
break
end
end
end
vim.keymap.set('v', '<leader>ce', M.send_selection, { desc = 'Send selection to Claude' })
Select a function in Visual mode, press <leader>ce, and the code is pasted into Claude Code with “Explain this code:” prepended.
Shell Integration for Context
Claude Code works best when it has context. Shell functions that pre-populate Claude with relevant information:
# In ~/.zshrc or ~/.bashrc
# Start Claude with current git status as context
claude-status() {
local context
context="Current git status:\n$(git status --short)\n\nRecent commits:\n$(git log --oneline -5)"
echo -e "$context" | claude --continue
}
# Start Claude focused on a specific file
claude-file() {
local file="$1"
if [[ -z "$file" ]]; then
echo "Usage: claude-file <path>"
return 1
fi
echo "I'm going to work on $file. Please read it first." | claude
}
# Start Claude with a test failure
claude-fix() {
local test_output
test_output=$(npm test -- --run 2>&1 | tail -50)
echo "Fix these failing tests:\n\n$test_output" | claude
}
Usage:
# After running tests and seeing failures:
claude-fix # Claude sees the test output immediately
# Before asking about a file:
claude-file src/api/auth.ts # Claude reads the file as first action
Efficient Claude Code Patterns in Terminal Workflows
Using CLAUDE.md for Shell Context
# project-name
## Development Environment
- Editor: Neovim (with LSP for TypeScript, ESLint + Prettier)
- Test runner: `npm test` (vitest, watch mode with `npm test -- --watch`)
- Lint: `npm run lint` (ESLint + Prettier check)
- Dev server: `npm run dev` (starts on :3000)
- Build: `npm run build`
- Database migrations: `npm run migrate` (knex)
## Workflow Notes
- I use tmux with Neovim in left pane, terminal in right
- Prefer `git add -p` for staged commits (I review hunks)
- Don't make git commits without asking — I stager selectively
The workflow note at the bottom prevents Claude Code from running git add -A && git commit without your review — important when you use git add -p to control what goes into each commit.
Terminal-First Debugging
There's a segfault in the Rust binary at startup.
I'm getting this in gdb: (paste backtrace)
Find the root cause.
Claude Code reads the backtrace, searches the source files, and identifies the cause — all while staying in your terminal environment. No copy-pasting into a browser tab.
The CLI workflow: run program in terminal → pipe output to Claude → get fix → apply with Claude Code → repeat. This tight loop is faster than switching between editor and browser.
Working with Large Codebases
Claude Code builds its own understanding of the codebase when it starts a session. In a Neovim workflow, you can prime it:
# Start Claude with context about what you're working on
claude <<'EOF'
I'm about to work on the authentication module (src/auth/).
The main entry is src/auth/index.ts. I'm debugging a JWT refresh token issue.
Please read the auth directory structure first.
EOF
Or use /init to generate a CLAUDE.md that gives Claude Code project structure instantly:
/init
Claude Code reads your project and generates CLAUDE.md covering architecture, key files, and conventions — which it then uses automatically in every subsequent session.
Zellij as an Alternative to tmux
I prefer Zellij over tmux.
Show me the equivalent layout for Claude Code development.
// ~/.config/zellij/layouts/dev.kdl
layout {
pane split_direction="vertical" {
pane {
name "editor"
command "nvim"
args "."
size "65%"
}
pane {
name "claude"
command "claude"
size "35%"
}
}
}
# Launch with: zellij --layout dev
alias dev='zellij --layout ~/.config/zellij/layouts/dev.kdl'
For Claude Code productivity patterns that work regardless of editor, see the productivity tips guide. For hooks that automate actions when Claude Code modifies files, see the hooks guide — hooks integrate cleanly into terminal workflows. The Claude Skills 360 bundle includes CLI and terminal workflow skill sets. Start with the free tier to try terminal-first prompt patterns.