claudecode.nvim: Neovim에서 Claude Code 쓰기
Neovim에서 코딩을 하다가 Claude한테 물어보고 싶은 게 생기면 보통 어떻게 하시나요?
대부분은 별도 터미널을 띄워두고 거기에 claude 명령을 입력해서 대화하시죠.
그런데 작업 중인 코드 일부를 통째로 보내고 싶거나, Claude가 제안한 변경 사항을 그대로 파일에 반영하고 싶을 때는 복사 붙여넣기를 반복하느라 흐름이 자꾸 끊깁니다. 😅
claudecode.nvim은 이 끊김을 없애주는 Neovim 플러그인입니다. 에디터 안에서 바로 Claude Code 터미널을 띄우고, 시각 모드로 선택한 코드를 한 번에 전송하고, Claude가 제안한 변경 사항을 Neovim의 익숙한 diff 화면으로 검토할 수 있어요.
이 글에서는 claudecode.nvim의 동작 원리부터 설치, 자주 쓰는 워크플로우, 설정 커스터마이징까지 정리해보겠습니다.
claudecode.nvim은 어떻게 동작하나요?
기존 Neovim의 LSP 플러그인은 보통 외부 프로세스를 자식 프로세스로 띄우고 stdin/stdout으로 통신합니다. claudecode.nvim도 비슷할 거라고 생각하기 쉬운데, 실제 구조는 좀 다릅니다.
플러그인이 시작될 때 임의의 포트를 골라서 WebSocket 서버를 먼저 띄웁니다.
그리고 이 포트 정보를 ~/.claude/ide/[port].lock 파일에 적어둬요.
그다음 Claude Code CLI가 환경 변수를 통해 이 락 파일을 읽고 IDE 측 서버에 붙는 구조입니다.
일단 연결되면 두 프로세스는 MCP(Model Context Protocol) 메시지를 주고받습니다. Claude는 이 채널을 통해 현재 열린 버퍼 정보, 커서 위치, 시각 모드로 선택된 영역을 실시간으로 알 수 있고요. 플러그인 쪽에서는 Claude가 제안한 파일 변경 사항을 받아 Neovim의 diff 창으로 띄워주는 식이에요.
플러그인 본체는 외부 의존성 없이 순수 Lua로 작성돼 있어서 NodeJS나 Python 같은 런타임을 따로 깔 필요가 없습니다. 터미널을 띄우는 부분만 snacks.nvim에 위임하고, 나머지는 자체 구현이에요.
설치 전에 챙길 것
먼저 Claude Code CLI가 시스템에 설치되어 있어야 합니다. 설치 방법과 기본 사용법은 Claude Code 입문 가이드에 정리해뒀으니 아직 안 깔았다면 그쪽을 먼저 참고하세요.
플러그인 매니저는 lazy.nvim을 기준으로 설명할 텐데, packer.nvim이나 vim-plug를 쓰고 있어도 같은 저장소(coder/claudecode.nvim)를 추가하면 됩니다.
NeoVim 입문 가이드에서 lazy.nvim 부트스트랩까지 마쳤다면 바로 다음 단계로 넘어가도 좋아요.
LazyVim 사용자라면 추가 설치 없이 lua/plugins/ 아래에 파일 하나만 만들면 됩니다.
Neovim 버전은 0.8 이상이어야 하고, snacks.nvim이 터미널 창을 띄우는 역할을 하니 의존성으로 함께 깔려야 합니다. LazyVim에는 snacks가 이미 들어 있어서 따로 신경 쓸 일이 없고요.
설치하기
플러그인 스펙은 Neovim 설정 디렉토리(~/.config/nvim/) 아래의 lua/plugins/ 폴더에 새 파일로 만듭니다.
LazyVim starter를 그대로 따라 설치했다면 이 폴더가 이미 만들어져 있을 거예요.
직접 구성한 환경이라 폴더가 없다면 한 번만 만들어두면 됩니다.
$ mkdir -p ~/.config/nvim/lua/plugins
이 폴더에 어떤 이름으로 .lua 파일을 만들어도 lazy.nvim이 자동으로 읽어들입니다.
플러그인마다 파일을 분리해도 좋고, ai.lua 한 파일에 Claude Code, Copilot 같은 AI 관련 설정을 묶어둬도 됩니다.
여기서는 알기 쉽게 claudecode.lua로 만들어볼게요.
return {
{
"coder/claudecode.nvim",
dependencies = { "folke/snacks.nvim" },
config = true,
keys = {
{ "<leader>ac", "<cmd>ClaudeCode<cr>", desc = "Toggle Claude" },
{ "<leader>af", "<cmd>ClaudeCodeFocus<cr>", desc = "Focus Claude" },
{ "<leader>as", "<cmd>ClaudeCodeSend<cr>", mode = "v", desc = "Send selection" },
{ "<leader>ab", "<cmd>ClaudeCodeAdd %<cr>", desc = "Add buffer" },
{ "<leader>aa", "<cmd>ClaudeCodeDiffAccept<cr>", desc = "Accept diff" },
{ "<leader>ad", "<cmd>ClaudeCodeDiffDeny<cr>", desc = "Deny diff" },
},
},
}
config = true는 lazy.nvim에 “이 플러그인의 setup()을 빈 옵션으로 호출해줘”라는 의미예요.
세부 설정을 바꾸고 싶지 않다면 이대로 두면 됩니다.
설치 후 Neovim을 재시작하면 lazy.nvim이 자동으로 플러그인을 받고, :ClaudeCode 명령이 등록됩니다.
처음엔 키 매핑을 다 외울 필요 없이 <leader>ac(터미널 토글)와 <leader>as(시각 선택 보내기) 두 개만 손에 익혀도 충분해요.
첫 사용
이제 일반 모드에서 <leader>ac(또는 :ClaudeCode)을 눌러볼 차례입니다.
화면 오른쪽에 터미널 창이 열리고 Claude Code의 프롬프트가 나타납니다.
Claude 프롬프트 안에서는 <leader>ac 입력이 그대로 터미널로 흘러가니까, Ctrl + h로 왼쪽 코드 창으로 돌아간 뒤 같은 단축키를 누르면 창이 숨겨져요.
흐름을 직접 해보면 이렇게 흘러갑니다.
코드 일부를 시각 모드(v)로 블록 선택만 해두면 그것만으로 Claude가 선택 영역을 알아챕니다.
claudecode.nvim의 기본 옵션 track_selection = true이 비주얼 선택 정보를 실시간으로 IDE 측 MCP 서버에 흘려보내고 있거든요.
그래서 “이 함수 리팩터링해줘” 같은 짧은 지시만 줘도 Claude가 어떤 파일의 어디를 봐야 할지 정확히 알게 됩니다.
선택을 더 명시적으로 박아두고 싶을 때는 <leader>as(:ClaudeCodeSend)를 누르세요.
이 명령은 선택 영역을 Claude 입력창에 @src/auth/login.ts#L20-45 같은 참조로 고정시킵니다.
가벼운 단발성 질문에는 자동 추적만으로 충분하지만, 여러 영역을 차례로 모아두거나 긴 대화에서 특정 코드를 계속 가리키게 하고 싶다면 명시적 전송이 정확도 면에서 유리해요.
Claude가 답변에서 코드 변경을 제안하면 Edit 도구가 호출되면서 Neovim에 새 diff 창이 뜹니다.
왼쪽이 원본, 오른쪽이 제안된 버전이에요.
내용을 보고 마음에 들면 <leader>aa로 수락하고, 영 아니다 싶으면 <leader>ad로 거부하면 됩니다.
다른 에디터들이 별도 사이드 패널에 변경 미리보기를 띄우는 것과 달리, Neovim 사용자에겐 이미 익숙한 :vimdiff UI 그대로라 학습 비용이 거의 없어요.
파일과 라인 범위를 컨텍스트로 추가하기
선택 영역 전송이 즉석에서 도움을 청하는 방식이라면, :ClaudeCodeAdd는 좀 더 의도적으로 컨텍스트를 쌓는 명령입니다.
:ClaudeCodeAdd src/auth/login.ts
:ClaudeCodeAdd src/auth/login.ts 10 50
첫 번째 줄은 파일 전체를 컨텍스트에 추가합니다.
두 번째 줄처럼 시작 라인과 끝 라인을 적으면 그 범위만 추가되고요.
%를 인자로 주면 현재 버퍼의 파일이 들어가서 <leader>ab처럼 매핑해두면 빠르게 부를 수 있습니다.
여러 파일을 미리 추가해두고 시작하면 “이 모듈들의 인터페이스를 이렇게 바꾸려고 하는데 영향받는 곳 알려줘” 같은 광범위한 질문을 더 정확히 받을 수 있어요. 선택 영역 보내기는 한 함수에 집중할 때, 파일 추가는 여러 파일을 함께 검토할 때라고 구분해서 쓰면 깔끔합니다.
변경 사항 diff로 검토하기
Claude가 파일 수정을 제안하면 Neovim에 diff가 뜬다고 했는데, 이게 실제 어떻게 보이는지 좀 더 살펴볼게요.
기본은 수직 분할입니다.
원본과 제안 버전이 좌우로 나란히 열리고, [c와 ]c로 변경 지점 사이를 이동할 수 있어요.
Vim의 diff 모드 기본 매핑이라 이미 익숙한 분이 많을 겁니다.
가로 분할이 편하다면 설정에서 바꿀 수 있습니다.
return {
{
"coder/claudecode.nvim",
opts = {
diff_opts = {
layout = "horizontal", -- "vertical"이 기본
open_in_new_tab = false, -- 새 탭에서 열고 싶다면 true
keep_terminal_focus = false,
},
},
},
}
open_in_new_tab = true로 두면 diff가 별도 탭에서 열려서 작업 중인 창 배치를 흐트러뜨리지 않습니다.
화면 분할을 많이 쓰는 분이라면 이 옵션이 유용해요.
부분 수락도 가능합니다.
diff 화면에서 변경 사항 일부만 골라 채택하고 싶다면 일반 Vim diff 명령(do, dp)으로 직접 편집한 다음 :w로 저장하면 그 상태가 그대로 적용돼요.
<leader>aa는 통째로 수락, :w는 편집한 결과 그대로 수락이라고 기억해두시면 됩니다.
다른 IDE 통합과 비교했을 때 Neovim 쪽이 자연스러운 지점이 바로 여기예요.
별도 UI를 학습하는 게 아니라 이미 알고 있던 do/dp를 그대로 쓰니까 변경 단위를 손쉽게 골라 채택할 수 있거든요.
자주 쓰는 명령 정리
claudecode.nvim에는 기본 키 매핑이 정해져 있지 않습니다.
앞서 lazy.nvim 스펙의 keys 항목에 직접 적은 게 그래서예요.
이 부분은 사람마다 선호가 갈리니까, 위 예시를 그대로 써도 좋고 자기 손에 맞게 조정해도 좋습니다.
자주 쓰는 명령을 한 번 더 정리해볼게요.
:ClaudeCode— 터미널 창을 토글합니다.:ClaudeCodeFocus— 창이 닫혀 있으면 열고, 열려 있으면 포커스를 옮깁니다.:ClaudeCodeSend— 시각 모드에서 선택한 영역을 컨텍스트로 보냅니다.:ClaudeCodeAdd <file> [start] [end]— 파일 전체나 라인 범위를 추가합니다.:ClaudeCodeDiffAccept— 제안된 변경을 수락합니다.:ClaudeCodeDiffDeny— 제안된 변경을 거부합니다.:ClaudeCodeSelectModel— 모델을 선택하고 새 세션을 시작합니다.
명령은 모두 일반 Ex 명령이라 :을 직접 입력해서 쓰거나, lazy 스펙처럼 키에 매핑해두고 쓰면 됩니다.
터미널 위치와 모양 커스터마이징
기본은 화면 오른쪽에 30% 너비의 세로 분할로 터미널이 열립니다.
왼쪽이 더 익숙하거나 너비를 다르게 두고 싶다면 terminal 옵션을 만져주세요.
opts = {
terminal = {
split_side = "left", -- "right"가 기본
split_width_percentage = 0.4, -- 0.30이 기본
provider = "snacks", -- "auto" | "snacks" | "native" | "external" | "none"
auto_close = true,
},
}
provider를 "native"로 바꾸면 Neovim 내장 터미널을 그대로 쓰고, snacks.nvim 의존성도 빠집니다.
대신 snacks가 제공하는 부드러운 창 전환 같은 편의 기능은 못 누리는 거고요.
“외부 터미널 멀티플렉서를 이미 쓰고 있어서 플러그인이 손대는 게 싫다”는 분에게는 "external" 옵션도 있습니다.
이 경우 플러그인은 WebSocket 서버만 띄우고 터미널은 알아서 띄우는 구조가 돼요.
tmux나 Zellij 같은 도구로 패널을 미리 잡아둔 상태에서 거기서 claude 명령을 쳐주면 됩니다.
플로팅 창으로 띄우고 싶다면 snacks 옵션을 통해 모양을 잡을 수 있어요.
opts = {
terminal = {
provider = "snacks",
snacks_win_opts = {
position = "float",
width = 0.8,
height = 0.8,
border = "rounded",
},
},
}
이렇게 두면 화면 가운데에 큰 둥근 모서리 창이 뜹니다. 좌우 분할이 답답하게 느껴진다면 한 번 시도해볼 만해요.
LazyVim에 깔끔하게 통합하기
LazyVim 사용자라면 앞서 본 lua/plugins/claudecode.lua를 직접 만들 필요가 없습니다.
LazyVim이 lazyvim.plugins.extras.ai.claudecode라는 공식 extra를 이미 내장하고 있어서, 한 번의 토글로 플러그인 설치, 키매핑, which-key 그룹, 파일 탐색기 통합까지 한꺼번에 켜집니다.
가장 쉬운 방법은 :LazyExtras 명령입니다.
:LazyExtras
목록에서 ai.claudecode를 찾아 x로 토글하고 q로 닫은 뒤 :Lazy sync로 동기화하면 끝이에요.
이때 LazyVim이 활성화 상태를 lazyvim.json 파일의 extras 배열에 자동으로 기록합니다.
이 파일을 Git으로 커밋해두면 dotfiles로 환경을 그대로 옮길 수 있어요.
{
"extras": ["lazyvim.plugins.extras.ai.claudecode"]
}
직접 이 JSON을 편집해서 extras 배열에 줄을 추가해도 동일한 결과가 됩니다.
이 extra가 등록해주는 키매핑은 다음과 같습니다.
| 키 매핑 | 동작 |
|---|---|
<leader>ac | Claude 창 토글 |
<leader>af | Claude 창에 포커스 |
<leader>ar | 이전 세션 이어가기 (--resume) |
<leader>aC | 마지막 세션 계속하기 (--continue) |
<leader>ab | 현재 버퍼를 컨텍스트에 추가 |
<leader>as (비주얼) | 선택 영역 보내기 |
<leader>as (탐색기) | 커서 위치 파일 추가 (NvimTree/neo-tree/oil) |
<leader>aa | diff 변경 수락 |
<leader>ad | diff 변경 거부 |
<leader>a는 LazyVim에서 AI 그룹으로 비어 있어서 위 매핑들이 충돌 없이 자연스럽게 들어갑니다.
<leader>만 누르고 잠깐 기다리면 which-key 팝업에 +ai 그룹과 함께 어떤 키가 어떤 동작을 하는지 한눈에 보이니 굳이 외울 필요가 없어요.
LazyVim의 다른 AI 통합인 GitHub Copilot과 같이 쓰는 것도 가능합니다. Copilot이 인라인 자동 완성을 담당하고, Claude는 좀 더 큰 단위의 리팩터링이나 설명 같은 대화형 작업을 담당하는 식으로 역할을 나누면 깔끔해요.
자주 마주치는 문제
설치는 끝났는데 :ClaudeCode을 눌러도 아무 일이 안 일어난다면 두 가지를 먼저 확인해보세요.
첫째로 claude 명령이 PATH에 잡혀 있는지입니다.
터미널에서 직접 claude --version을 쳐보고 응답이 나와야 플러그인도 같은 바이너리를 찾을 수 있어요.
응답이 없다면 Claude Code 입문 가이드에서 설치 방법을 다시 확인해주세요.
둘째로 의존성으로 적은 snacks.nvim이 실제로 설치됐는지 확인합니다.
:Lazy로 lazy.nvim 대시보드를 열어 snacks.nvim이 목록에 보이는지 보면 됩니다.
LazyVim이 아닌 직접 구성한 환경이라면 dependencies에 적었어도 처음 한 번은 :Lazy sync로 동기화해줘야 깔립니다.
diff 창이 떴는데 변경이 적용이 안 되거나 이상하게 동작한다면 자동 저장 플러그인을 쓰고 있는지도 살펴보세요.
auto-save류 플러그인이 diff 버퍼를 잘못 잡으면 충돌이 날 수 있어서, 해당 플러그인의 제외 패턴에 claudecode.nvim의 임시 버퍼를 추가해주거나 차라리 <leader>aa로만 수락하는 워크플로우로 가는 게 안전합니다.
마치며
claudecode.nvim은 “Claude Code를 별도 터미널에서 쓰던 흐름을 그대로 Neovim 안으로 옮겨오는” 플러그인입니다. 별도 IDE를 쓰는 분들이 누리던 인라인 diff 검토와 선택 영역 전송 같은 편의를, 키보드 흐름이 끊기지 않는 형태로 그대로 가져올 수 있어요.
도입을 고민 중이라면 우선 <leader>ac로 토글하고 <leader>as로 시각 선택을 보내는 두 가지만 손에 익혀보세요.
이 두 개만 익숙해져도 Claude와 코드를 주고받는 속도가 눈에 띄게 빨라집니다.
나머지 매핑은 필요해질 때 하나씩 추가해도 늦지 않아요.
Claude Code 자체의 슬래시 명령이나 설정에 대해 더 알고 싶다면 Claude Code 슬래시 명령 정리와 Claude Code 설정 가이드도 함께 읽어보면 좋습니다. 플러그인 측 옵션과 CLI 측 옵션이 서로 보완 관계라 양쪽을 같이 알면 워크플로우를 더 정교하게 다듬을 수 있어요.
더 자세한 내용은 claudecode.nvim 공식 저장소를 참고하세요.
This work is licensed under
CC BY 4.0