이 글은 Vim 단축키 시리즈의 두 번째 글이다.
- Vi/Vim 단축키 종합 가이드: 기본부터 실전까지
- Neovim 단축키 가이드: Vim을 넘어서는 기능들 ← 현재 글
Vi와 뭐가 다른가
1편에서 다룬 단축키는 Vi/Vim 어디서든 동작하는 보편적인 키다. 이 글에서 다루는 것은 Neovim에서만 쓸 수 있는 기능들이다.
Neovim이 Vim 위에 추가하는 것:
- 내장 LSP — 코드 분석, 정의 이동, 자동완성을 플러그인 없이
- 내장 터미널 — 에디터 안에서 셸 실행
- Lua 설정 — Vimscript 대신 Lua로 설정과 플러그인
- 플러그인 생태계 — Telescope, Treesitter, LSP 기반 플러그인들
아래 단축키 중 <leader> 키가 나오면, 대부분의 Neovim 설정에서 Space로 매핑되어 있다.
내장 LSP 단축키
LSP(Language Server Protocol)를 설정하면 IDE 수준의 코드 내비게이션이 가능해진다.
코드 내비게이션
| 키 | 동작 |
|---|---|
gd | 정의로 이동 (Go to Definition) |
gD | 선언으로 이동 (Go to Declaration) |
gr | 참조 목록 (Go to References) |
gi | 구현으로 이동 (Go to Implementation) |
K | 커서 아래 심볼 정보 표시 (hover) |
Ctrl-] | 정의로 이동 (태그 스택 방식) |
gd로 이동한 후 Ctrl-o로 이전 위치로 돌아올 수 있다.
코드 액션
| 키 | 동작 |
|---|---|
<leader>ca | 코드 액션 (자동 수정, import 추가 등) |
<leader>rn | 심볼 이름 변경 (rename) |
<leader>f | 포맷팅 |
진단 (Diagnostics)
| 키 | 동작 |
|---|---|
[d | 이전 진단(에러/경고)으로 이동 |
]d | 다음 진단으로 이동 |
<leader>e | 현재 줄 진단 메시지 표시 |
<leader>q | 진단 목록 열기 (quickfix) |
자동완성
| 키 | 동작 |
|---|---|
Ctrl-Space | 자동완성 메뉴 열기 |
Tab / Shift-Tab | 다음 / 이전 항목 |
Enter | 선택 확정 |
Ctrl-e | 자동완성 취소 |
Ctrl-n / Ctrl-p | 다음 / 이전 (내장 완성) |
시그니처 도움말
| 키 | 동작 |
|---|---|
Ctrl-k | 함수 시그니처 표시 (Insert 모드) |
함수 호출 시 인자를 입력하는 중에 Ctrl-k를 누르면 파라미터 정보가 뜬다.
내장 터미널
Neovim 안에서 셸을 실행할 수 있다.
기본 사용
| 명령 | 동작 |
|---|---|
:terminal | 현재 윈도우에서 터미널 열기 |
:split | terminal | 가로 분할 후 터미널 |
:vsplit | terminal | 세로 분할 후 터미널 |
터미널 모드 키
| 키 | 동작 |
|---|---|
i / a | 터미널 입력 모드 진입 |
Ctrl-\ Ctrl-n | Normal 모드로 복귀 |
터미널에서 Normal 모드로 돌아오면 출력 내용을 Vim 명령으로 검색하거나 복사할 수 있다.
분할 터미널 워크플로우
+------------------+------------------+
| Code (Neovim) | Terminal (shell) |
| | |
+------------------+------------------+
코드를 편집하면서 옆 터미널에서 빌드/테스트를 실행한다. Ctrl-w l로 터미널로 이동, Ctrl-w h로 코드로 복귀.
플로팅 터미널: 많은 설정에서 Ctrl-; 또는 <leader>t로 플로팅 터미널을 토글한다. 화면을 가리지 않고 빠르게 명령을 실행할 수 있다.
마우스 활용
Neovim에서 mouse=a 설정을 켜면 마우스를 활용할 수 있다.
기본 동작
| 동작 | 결과 |
|---|---|
| 클릭 | 커서 이동 |
| 드래그 | Visual 모드로 텍스트 선택 |
| 더블클릭 | 단어 선택 (Visual) |
| 트리플클릭 | 줄 전체 선택 (Visual Line) |
| Shift + 클릭 | 현재 커서부터 클릭 위치까지 선택 |
| 스크롤 휠 | 페이지 스크롤 |
마우스 + 키보드 하이브리드
마우스로 선택한 후 키보드로 조작:
1. 마우스 드래그로 영역 선택 (Visual 모드 진입)
2. d, c, y 등 키보드 명령 실행
예: 마우스로 코드 블록을 드래그 선택 → > (들여쓰기), y (복사), d (삭제)
언제 마우스를 쓰는가
키보드가 더 빠른 경우:
- 같은 줄 내 이동 (
f,w,0,$) - 구조적 선택 (
ci",vi{,vap) - 반복 작업 (
., 매크로)
마우스가 더 빠른 경우:
- 먼 거리 점프 — 화면에 보이는 임의의 위치로
- 코드 리뷰 — 여기저기 클릭하며 읽을 때
- 비구조적 선택 — 단어나 괄호 경계와 무관한 임의 영역
키보드 순수주의에 집착할 필요 없다. 둘 다 쓰면 된다.
필수 플러그인 단축키
Neovim 생태계의 핵심 플러그인들과 주요 단축키를 정리한다.
Telescope — 퍼지 파인더
| 키 | 동작 |
|---|---|
<leader>ff | 파일 찾기 |
<leader>fg | 텍스트 검색 (live grep) |
<leader>fb | 열린 버퍼 목록 |
<leader>fh | 도움말 태그 검색 |
Telescope 창 안에서:
| 키 | 동작 |
|---|---|
Ctrl-j / Ctrl-k | 위아래 이동 |
Enter | 선택 항목 열기 |
Ctrl-x | 가로 분할로 열기 |
Ctrl-v | 세로 분할로 열기 |
Ctrl-t | 새 탭으로 열기 |
Esc | 닫기 |
Neo-tree — 파일 탐색기
| 키 | 동작 |
|---|---|
<leader>e | 파일 트리 토글 |
Neo-tree 안에서:
| 키 | 동작 |
|---|---|
Enter / o | 파일 열기 / 폴더 토글 |
a | 새 파일/폴더 생성 |
d | 삭제 |
r | 이름 변경 |
c / m | 복사 / 이동 |
y | 경로 복사 |
/ | 필터 검색 |
Comment.nvim — 주석
| 키 | 동작 |
|---|---|
gcc | 현재 줄 주석 토글 |
gc{motion} | 범위 주석 토글 (예: gcap 문단) |
gc (Visual) | 선택 영역 주석 토글 |
gbc | 현재 줄 블록 주석 토글 |
Vim의 Ctrl-v → I → // 방식보다 훨씬 간편하다. 언어별 주석 형식도 자동 감지한다.
nvim-surround — 감싸기
| 키 | 동작 | 예시 |
|---|---|---|
ys{motion}{char} | 감싸기 추가 | ysiw" → word를 “word"로 |
cs{old}{new} | 감싸기 변경 | cs"' → “text"를 ’text’로 |
ds{char} | 감싸기 삭제 | ds" → “text"를 text로 |
S{char} (Visual) | 선택 영역 감싸기 | 선택 후 S( → (선택 영역)으로 |
Surround 문법:
ys + iw + " → 단어를 "로 감싸기
ys + ap + { → 문단을 {로 감싸기
cs + " + ' → "를 '로 변경
ds + ( → (를 삭제
이것도 동사(ys/cs/ds) + 명사(motion/text object) + 감싸기 문자의 문법이다.
Flash / Hop — 화면 내 빠른 점프
| 키 | 동작 |
|---|---|
s{char}{char} | 2글자 입력 후 레이블로 점프 |
화면에 보이는 위치로 2-3번의 키 입력만으로 이동한다. f/t는 같은 줄로 제한되지만, Flash는 화면 전체에서 동작한다.
Gitsigns — Git 표시
| 키 | 동작 |
|---|---|
]c / [c | 다음 / 이전 변경 사항으로 이동 |
<leader>hs | hunk 스테이지 |
<leader>hr | hunk 리셋 |
<leader>hp | hunk 미리보기 (diff) |
<leader>hb | 줄 blame 표시 |
Which-key — 키 안내
| 동작 | 설명 |
|---|---|
<leader> 누르고 잠시 대기 | 사용 가능한 키 목록이 표시됨 |
단축키가 기억나지 않을 때 <leader>만 누르고 기다리면 된다. 어떤 키가 어떤 기능인지 팝업으로 보여준다.
Leader 키와 커스텀 매핑 전략
Space를 Leader로 쓰는 이유
vim.g.mapleader = " "
- 양손 어디서든 누르기 쉬운 위치
- 기본적으로 Normal 모드에서
Space는l과 같은 동작(쓸모 없음) - Neovim 커뮤니티의 사실상 표준
네이밍 규칙
잘 만들어진 설정은 Leader 뒤의 키가 일관된 체계를 따른다:
| 접두사 | 의미 | 예시 |
|---|---|---|
<leader>f | Find | ff(파일), fg(grep), fb(버퍼) |
<leader>b | Buffer | bn(다음), bp(이전), bd(닫기) |
<leader>g | Git | gs(status), gc(commit), gp(push) |
<leader>l | LSP | ld(정의), lr(참조), ln(rename) |
<leader>t | Terminal/Tab | tt(토글), tn(새 탭) |
<leader>w | Window | wv(세로분할), ws(가로분할) |
자주 쓰는 커스텀 매핑
-- 저장
vim.keymap.set("n", "<leader>w", ":w<CR>")
-- 창 이동 (Ctrl-h/j/k/l)
vim.keymap.set("n", "<C-h>", "<C-w>h")
vim.keymap.set("n", "<C-j>", "<C-w>j")
vim.keymap.set("n", "<C-k>", "<C-w>k")
vim.keymap.set("n", "<C-l>", "<C-w>l")
-- Visual 모드에서 들여쓰기 후 선택 유지
vim.keymap.set("v", "<", "<gv")
vim.keymap.set("v", ">", ">gv")
-- 줄 이동
vim.keymap.set("v", "J", ":m '>+1<CR>gv=gv")
vim.keymap.set("v", "K", ":m '<-2<CR>gv=gv")
-- 검색 하이라이트 제거
vim.keymap.set("n", "<leader>h", ":nohlsearch<CR>")
-- 시스템 클립보드 복사
vim.keymap.set({"n", "v"}, "<leader>y", '"+y')
마지막 <gv / >gv 매핑은 특히 유용하다. 기본 Vim에서는 >로 들여쓰기하면 Visual 선택이 해제되지만, 이 매핑을 쓰면 선택이 유지되어 연속으로 > >를 누를 수 있다.
클립보드 연동
기본 사용
"+y → 시스템 클립보드에 복사
"+p → 시스템 클립보드에서 붙여넣기
매번 "+를 치기 귀찮다면 설정에서:
vim.opt.clipboard = "unnamedplus"
이렇게 하면 y/p가 바로 시스템 클립보드를 사용한다.
SSH 원격에서 클립보드
SSH로 접속한 서버의 Neovim에서 복사한 텍스트를 로컬 클립보드로 보내려면 OSC 52를 지원하는 터미널이 필요하다.
지원 터미널: iTerm2, WezTerm, Alacritty, kitty, Windows Terminal
Neovim 0.10+ 에서는 OSC 52가 기본 지원된다. 별도 설정 없이 "+y가 SSH 환경에서도 로컬 클립보드에 복사된다.
Neovim 전용 편의 기능
명령/검색 히스토리 윈도우
| 키 | 동작 |
|---|---|
q: | 명령 히스토리를 편집 가능한 창으로 |
q/ | 검색 히스토리를 편집 가능한 창으로 |
일반 : 프롬프트와 달리, Vim 명령(검색, 편집, 이동)으로 이전 명령을 수정하고 실행할 수 있다. 긴 치환 명령을 재사용할 때 유용하다.
q:를 실수로 눌렀다면 :q로 닫으면 된다.
inccommand — 실시간 치환 미리보기
vim.opt.inccommand = "split"
:s/old/new/g를 입력하는 동안 실시간으로 변경 결과가 미리보기된다. 정규식이 맞는지 실행 전에 확인할 수 있다.
"split"으로 설정하면 화면 하단에 변경될 줄 목록이 표시된다. "nosplit"이면 본문에서 직접 하이라이트.
:lua 직접 실행
:lua print(vim.fn.expand("%")) " 현재 파일 경로
:lua print(vim.opt.tabstop:get()) " 탭 크기
:lua vim.lsp.buf.format() " LSP 포맷팅
설정을 바꾸거나 디버깅할 때 Lua 코드를 즉시 실행할 수 있다.
내장 diff 모드
nvim -d file1.txt file2.txt
또는 이미 열린 상태에서:
:diffthis " 현재 윈도우를 diff에 포함
:diffoff " diff 모드 해제
]c / [c " 다음/이전 변경으로 이동
do " diff obtain — 반대쪽 변경 가져오기
dp " diff put — 이쪽 변경 보내기
단축키 디버깅
단축키가 안 먹히거나 예상과 다르게 동작할 때:
매핑 확인
:map <leader>f " <leader>f에 뭐가 매핑되어 있는지
:nmap " Normal 모드 매핑 전체 목록
:imap " Insert 모드 매핑 전체
:vmap " Visual 모드 매핑 전체
:verbose map <leader>f " 어떤 파일에서 매핑했는지까지 표시
:verbose가 핵심이다. 키 충돌이 생겼을 때 어떤 플러그인이 해당 키를 가져갔는지 바로 알 수 있다.
Which-key 활용
Which-key 플러그인이 설치되어 있다면 <leader>를 누르고 기다리면 모든 매핑이 시각화된다. 키 충돌이 있으면 같은 접두사에 두 개 이상의 매핑이 보인다.
키가 안 먹힐 때 체크리스트
:verbose map <key>로 다른 플러그인이 덮어쓰지 않았는지 확인- 올바른 모드인지 확인 (
nmapvsimapvsvmap) - Leader 키가 제대로 설정되었는지:
:echo mapleader - 플러그인이 로드되었는지:
:Lazy check(lazy.nvim 사용 시)
마치며
Neovim은 Vim의 편집 철학 위에 현대적인 기능을 더한다. LSP로 IDE 수준의 코드 내비게이션, 내장 터미널로 에디터 밖을 나가지 않는 워크플로우, 플러그인으로 무한 확장.
추천 학습 순서:
- 1편의 Vim 기본을 먼저 익힌다
- LSP 단축키(
gd,K,gr)를 자주 쓰면서 습관을 만든다 - Telescope(
<leader>ff/fg)를 파일 탐색의 기본으로 삼는다 - Comment(
gcc), Surround(ys/cs/ds)를 익힌다 - 나머지는 필요할 때 하나씩 추가한다
한 번에 다 외우려 하지 말고, 매일 하나씩 새로운 키를 시도해보자.