Vi는 1976년 Bill Joy가 BSD Unix를 위해 작성한 텍스트 에디터다. 당시 터미널 환경에서 키보드만으로 효율적인 편집을 가능하게 한 혁신적인 도구였다. Vi의 핵심 아이디어인 **모달 편집(Modal Editing)**은 오늘날까지 살아 숨 쉰다.
Vim(Vi IMproved)은 1991년 Bram Moolenaar가 공개한 Vi의 대폭 확장 버전이다. 구문 강조, 플러그인 시스템, 다중 창, 매크로, 정규식 치환 등 수백 가지 기능이 추가되었다. Vim은 GNU/Linux 서버에 기본 탑재되어 전 세계 개발자와 시스템 관리자가 일상적으로 사용하는 표준 에디터가 되었다.
Neovim은 2014년에 시작된 Vim의 리팩토링 포크다. Lua 기반 설정, 내장 LSP(Language Server Protocol), 비동기 플러그인 API를 제공하며, VS Code 수준의 IDE 경험을 터미널에서 구현하는 것을 목표로 한다.
| 에디터 | 출시 | 특징 |
|---|
| Vi | 1976 | 모달 편집의 원조, 경량 |
| Vim | 1991 | 플러그인, 구문 강조, 매크로 |
| Neovim | 2014 | Lua API, 내장 LSP, 비동기 처리 |
- 어디서나 사용 가능: SSH 접속한 원격 서버, Docker 컨테이너, 임베디드 장치 — 거의 모든 Unix 환경에 Vi/Vim이 설치되어 있다.
- 손이 키보드를 벗어나지 않는다: 마우스 없이 모든 조작이 가능하므로 편집 속도가 극적으로 향상된다.
- 강력한 조합 언어:
d3w(단어 3개 삭제), ci"(따옴표 안 내용 변경) 처럼 동사+횟수+명사 구조로 복잡한 조작을 간결하게 표현한다. - 매크로와 자동화: 반복 작업을 매크로로 기록하여 수천 줄을 순식간에 변환한다.
- Vim 키바인딩의 범용성: VS Code, IntelliJ, Obsidian, Jupyter, bash readline, tmux copy mode 등 수십 가지 도구가 Vim 키바인딩을 지원한다. Vim을 배우면 모든 도구가 빨라진다.
Vim의 가장 중요한 특징은 모달 편집이다. 키를 누를 때의 동작이 현재 모드에 따라 완전히 달라진다.
| 모드 | 설명 | 진입 방법 | 탈출 방법 |
|---|
| Normal | 이동, 명령 실행 | <Esc>, <C-c> | — (기본 모드) |
| Insert | 텍스트 입력 | i, a, o, I, A, O, s, c | <Esc>, <C-c> |
| Visual | 문자 단위 선택 | v | <Esc>, v |
| Visual Line | 줄 단위 선택 | V | <Esc>, V |
| Visual Block | 블록(열) 단위 선택 | <C-v> | <Esc>, <C-v> |
| Command-line | : 명령 입력 | :, /, ?, ! | <Esc>, <CR> |
| Replace | 문자 덮어쓰기 | R | <Esc> |
┌─────────────────────────────────────────┐
│ Normal Mode │
│ (Vim 시작 시 / <Esc> 로 항상 복귀) │
└────┬───────┬───────┬────────────────────┘
│ │ │
i,a,o│ v,V│ :,/,?│
│ │ │
┌────▼──┐ ┌──▼────┐ ┌▼────────────┐
│Insert │ │Visual │ │Command-line │
│ Mode │ │ Mode │ │ Mode │
└───────┘ └───────┘ └─────────────┘
규칙: 언제든 <Esc>를 누르면 Normal Mode로 돌아간다. 방향을 잃었을 때 <Esc>를 2번 누르는 것이 Vim 생존 법칙 #1이다.
| 키 | 동작 |
|---|
h | 왼쪽 한 칸 |
j | 아래 한 줄 |
k | 위 한 줄 |
l | 오른쪽 한 칸 |
5j | 아래 5줄 (숫자 접두어 조합 가능) |
10k | 위 10줄 |
| 키 | 동작 |
|---|
w | 다음 단어 시작으로 이동 (구두점 구분) |
W | 다음 WORD 시작으로 이동 (공백 구분) |
b | 이전 단어 시작으로 이동 |
B | 이전 WORD 시작으로 이동 |
e | 현재/다음 단어 끝으로 이동 |
E | 현재/다음 WORD 끝으로 이동 |
ge | 이전 단어 끝으로 이동 |
소문자(w, b, e)는 구두점을 단어 경계로 인식하고, 대문자(W, B, E)는 공백만 경계로 인식한다. hello_world에서 w는 2번, W는 1번에 이동한다.
| 키 | 동작 |
|---|
0 | 줄의 맨 처음(컬럼 0)으로 이동 |
^ | 줄의 첫 번째 비공백 문자로 이동 |
$ | 줄의 맨 끝으로 이동 |
g_ | 줄의 마지막 비공백 문자로 이동 |
gg | 파일의 첫 번째 줄로 이동 |
G | 파일의 마지막 줄로 이동 |
42G | 42번 줄로 이동 |
:42 | 42번 줄로 이동 (명령 모드) |
% | 매칭되는 괄호/중괄호/대괄호로 이동 |
| 키 | 동작 |
|---|
<C-u> | 화면 절반 위로 스크롤 |
<C-d> | 화면 절반 아래로 스크롤 |
<C-f> | 화면 전체 아래로 스크롤 (Page Down) |
<C-b> | 화면 전체 위로 스크롤 (Page Up) |
H | 화면 맨 위 줄로 커서 이동 (High) |
M | 화면 중간 줄로 커서 이동 (Middle) |
L | 화면 맨 아래 줄로 커서 이동 (Low) |
zz | 현재 줄을 화면 중앙에 맞춤 |
zt | 현재 줄을 화면 상단에 맞춤 |
zb | 현재 줄을 화면 하단에 맞춤 |
| 키 | 동작 |
|---|
/pattern | 아래 방향으로 pattern 검색 |
?pattern | 위 방향으로 pattern 검색 |
n | 같은 방향으로 다음 검색 결과 |
N | 반대 방향으로 다음 검색 결과 |
* | 커서 아래 단어를 아래 방향으로 검색 |
# | 커서 아래 단어를 위 방향으로 검색 |
f{char} | 현재 줄에서 char를 앞 방향 검색, 그 위치로 이동 |
F{char} | 현재 줄에서 char를 뒤 방향 검색 |
t{char} | char 바로 앞으로 이동 (till) |
T{char} | char 바로 뒤(역방향)로 이동 |
; | f/F/t/T 방향으로 반복 |
, | f/F/t/T 역방향으로 반복 |
| 키 | 동작 |
|---|
<C-o> | 이전 커서 위치로 이동 (jump back) |
<C-i> | 다음 커서 위치로 이동 (jump forward) |
'' | 직전 점프 위치로 복귀 (작은따옴표 2번) |
m{a-z} | 현재 위치를 마크 a~z로 저장 |
'{a-z} | 마크로 이동 |
gd | 로컬 정의(declaration)로 이동 |
gD | 전역 정의로 이동 |
| 키 | 동작 |
|---|
i | 커서 앞에서 Insert Mode 진입 |
I | 줄의 첫 비공백 문자 앞에서 Insert Mode 진입 |
a | 커서 뒤에서 Insert Mode 진입 (append) |
A | 줄의 끝에서 Insert Mode 진입 |
o | 현재 줄 아래에 새 줄을 추가하고 Insert Mode 진입 |
O | 현재 줄 위에 새 줄을 추가하고 Insert Mode 진입 |
gi | 마지막으로 편집한 위치에서 Insert Mode 진입 |
| 키 | 동작 |
|---|
x | 커서 아래 문자 삭제 |
X | 커서 앞 문자 삭제 (Backspace) |
dd | 현재 줄 삭제 |
3dd | 현재 줄부터 3줄 삭제 |
D | 커서부터 줄 끝까지 삭제 (d$와 동일) |
dw | 커서부터 다음 단어 시작 전까지 삭제 |
de | 커서부터 단어 끝까지 삭제 |
d0 | 커서부터 줄 시작까지 삭제 |
dG | 현재 줄부터 파일 끝까지 삭제 |
dgg | 현재 줄부터 파일 시작까지 삭제 |
삭제된 텍스트는 레지스터에 저장되어 p로 붙여넣기할 수 있다. Vim의 삭제는 "잘라내기(Cut)"와 동일하다.
| 키 | 동작 |
|---|
r{char} | 커서 아래 문자를 char로 교체 (Normal Mode 유지) |
R | Replace Mode 진입 (연속 덮어쓰기) |
s | 커서 아래 문자 삭제 후 Insert Mode 진입 |
S | 현재 줄 내용 삭제 후 Insert Mode 진입 (cc와 동일) |
cw | 커서부터 단어 끝까지 변경 |
cc | 현재 줄 내용 변경 |
C | 커서부터 줄 끝까지 변경 (c$와 동일) |
c0 | 커서부터 줄 시작까지 변경 |
~ | 커서 아래 문자의 대소문자 토글 |
g~w | 단어의 대소문자 토글 |
guw | 단어를 소문자로 변환 |
gUw | 단어를 대문자로 변환 |
| 키 | 동작 |
|---|
yy | 현재 줄 복사 (yank) |
Y | 현재 줄 복사 (yy와 동일) |
3yy | 현재 줄부터 3줄 복사 |
yw | 커서부터 단어 끝까지 복사 |
y$ | 커서부터 줄 끝까지 복사 |
y0 | 커서부터 줄 시작까지 복사 |
p | 커서 뒤(아래)에 붙여넣기 |
P | 커서 앞(위)에 붙여넣기 |
gp | p와 동일하나 붙여넣기 후 커서를 붙여넣은 텍스트 끝으로 이동 |
"ayy | 레지스터 a에 현재 줄 복사 |
"ap | 레지스터 a의 내용 붙여넣기 |
| 키 | 동작 |
|---|
u | 마지막 변경 취소 (Undo) |
3u | 마지막 3개 변경 취소 |
<C-r> | Undo 취소 (Redo) |
U | 현재 줄에 대한 모든 변경 취소 |
| 키 | 동작 |
|---|
>> | 현재 줄 들여쓰기 |
<< | 현재 줄 내어쓰기 |
3>> | 3줄 들여쓰기 |
= | 자동 들여쓰기 (Visual 선택 후 또는 ==으로 현재 줄) |
== | 현재 줄 자동 들여쓰기 |
gg=G | 파일 전체 자동 들여쓰기 |
| 키 | 모드 | 설명 |
|---|
v | Visual (문자) | 문자 단위 선택 |
V | Visual Line | 줄 단위 선택 |
<C-v> | Visual Block | 열(column) 단위 블록 선택 |
gv | — | 이전 Visual 선택 영역 재선택 |
| 키 | 동작 |
|---|
d / x | 선택 영역 삭제 |
y | 선택 영역 복사 |
c | 선택 영역 삭제 후 Insert Mode 진입 |
> / < | 선택 영역 들여쓰기 / 내어쓰기 |
= | 선택 영역 자동 들여쓰기 |
~ | 선택 영역 대소문자 토글 |
u | 선택 영역 소문자 변환 |
U | 선택 영역 대문자 변환 |
: | 선택 영역에 명령 적용 (:'<,'>) |
o | 선택 영역의 반대 끝으로 커서 이동 |
Visual Block(<C-v>)은 여러 줄에 동시에 텍스트를 삽입하거나 삭제할 때 매우 유용하다.
예시: 여러 줄 앞에 // 주석 추가하기
1. <C-v>로 Visual Block 진입
2. j를 눌러 원하는 줄 수만큼 선택
3. I 를 눌러 블록 Insert Mode 진입
4.
5. <Esc> 를 누르면 모든 선택된 줄에
예시: 여러 줄의 특정 컬럼 내용 삭제
1. <C-v>로 Visual Block 진입
2. 원하는 범위 선택 (hjkl로 열 범위 조정 가능)
3. d로 삭제
텍스트 객체는 Vim 편집의 핵심 개념이다. {operator}{a|i}{object} 구조로 "동사 + 전치사 + 명사" 형태의 명령을 구성한다.
a (around): 객체와 주변 공백/구분자 포함i (inner): 객체 내부만 선택
| 객체 | i (inner) | a (around) |
|---|
w | 단어 내부 | 단어 + 주변 공백 |
W | WORD 내부 | WORD + 주변 공백 |
s | 문장 내부 | 문장 + 뒤 공백 |
p | 단락 내부 | 단락 + 앞뒤 빈 줄 |
" | "..." 안쪽 내용 | "..." 전체 |
' | '...' 안쪽 내용 | '...' 전체 |
` | `...` 안쪽 내용 | `...` 전체 |
( / ) | (...) 안쪽 | (...) 전체 |
[ / ] | [...] 안쪽 | [...] 전체 |
{ / } | {...} 안쪽 | {...} 전체 |
< / > | <...> 안쪽 | <...> 전체 |
t | XML/HTML 태그 내부 | 태그 포함 전체 |
| 명령 | 동작 | 예시 상황 |
|---|
diw | 커서 아래 단어 삭제 | hello 위에서 → 단어 삭제 |
daw | 커서 아래 단어 + 공백 삭제 | 문장 중 단어 완전 제거 |
ci" | "..." 안 내용 변경 | "old" → 따옴표 유지하고 내용 교체 |
ca" | "..." 전체 변경 | "old" → 따옴표까지 교체 |
di( | (...) 안 내용 삭제 | 함수 인자 전체 삭제 |
da( | (...) 전체 삭제 | 괄호 포함 삭제 |
yip | 현재 단락 복사 | 단락 전체 복사 |
dap | 현재 단락 삭제 | 단락 전체 삭제 |
vit | HTML 태그 내부 Visual 선택 | <div>content</div>에서 content 선택 |
cit | HTML 태그 내부 변경 | 태그 내용 교체 |
=i{ | 중괄호 안 자동 들여쓰기 | 함수 바디 전체 정렬 |
>i{ | 중괄호 안 들여쓰기 추가 | |
7. 명령 모드 (Command-line Mode)
| 명령 | 동작 |
|---|
:w | 저장 |
:w filename | 다른 이름으로 저장 |
:q | 종료 (변경 없을 때) |
:q! | 변경 사항 무시하고 강제 종료 |
:wq | 저장 후 종료 |
:wq! | 강제 저장 후 종료 |
:x | 변경 사항이 있을 때만 저장 후 종료 (ZZ와 동일) |
ZZ | :x와 동일 |
ZQ | :q!와 동일 |
:e filename | 파일 열기 |
:e! | 현재 파일 변경 사항 버리고 재로드 |
:r filename | 파일 내용을 현재 위치에 삽입 |
:r !command | 명령 실행 결과를 현재 위치에 삽입 |
| 명령 | 동작 |
|---|
:%s/old/new/g | 파일 전체에서 old를 new로 모두 치환 |
:%s/old/new/gc | 전체 치환, 각 항목마다 확인 |
:%s/old/new/gi | 대소문자 무시하고 전체 치환 |
:5,20s/old/new/g | 5~20번 줄에서 치환 |
:'<,'>s/old/new/g | Visual 선택 영역에서 치환 |
:%s/\s\+$//e | 줄 끝 공백 제거 |
:%s/^/ / | 모든 줄 앞에 공백 4개 추가 |
| 명령 | 동작 |
|---|
:!command | 외부 명령 실행 (예: :!ls -la) |
:!python % | 현재 파일을 Python으로 실행 |
:%!command | 파일 전체를 command의 입력으로 넘기고 출력으로 교체 |
:.!command | 현재 줄을 command의 입력으로 넘기고 출력으로 교체 |
:shell | 임시로 쉘로 나가기 (exit으로 복귀) |
| 범위 표현 | 의미 |
|---|
:5 | 5번 줄 |
:5,10 | 5번에서 10번 줄 |
:% | 파일 전체 (1,$와 동일) |
:. | 현재 줄 |
:.,$ | 현재 줄부터 파일 끝 |
:'<,'> | Visual 선택 영역 |
:.,+5 | 현재 줄부터 5줄 |
**버퍼(Buffer)**는 메모리에 열려 있는 파일이다. 여러 파일을 동시에 열어 편집할 수 있다.
| 명령 | 동작 |
|---|
:ls / :buffers | 열려 있는 버퍼 목록 표시 |
:b2 | 2번 버퍼로 전환 |
:bn | 다음 버퍼로 전환 |
:bp | 이전 버퍼로 전환 |
:bd | 현재 버퍼 닫기 |
:ba | 모든 버퍼를 분할 창으로 열기 |
| 명령 | 동작 |
|---|
:sp / :split | 수평 분할 (horizontal split) |
:vsp / :vsplit | 수직 분할 (vertical split) |
:sp filename | 파일을 새 수평 분할 창에서 열기 |
:vsp filename | 파일을 새 수직 분할 창에서 열기 |
<C-w>s | 수평 분할 (Normal Mode) |
<C-w>v | 수직 분할 (Normal Mode) |
<C-w>w | 다음 창으로 포커스 이동 |
<C-w>h/j/k/l | 방향으로 창 이동 |
<C-w>H/J/K/L | 창을 해당 방향으로 이동 |
<C-w>= | 모든 창 크기 균등 분배 |
<C-w>+ / <C-w>- | 수평 크기 조정 |
Ctrl-w > / Ctrl-w < | 수직 크기 조정 |
Ctrl-w _ | 현재 창 수직 최대화 |
Ctrl-w | | 현재 창 수평 최대화 |
<C-w>q | 현재 창 닫기 |
<C-w>o | 다른 모든 창 닫기 (only) |
| 명령 | 동작 |
|---|
:tabnew | 새 탭 열기 |
:tabnew filename | 파일을 새 탭에서 열기 |
gt | 다음 탭으로 이동 |
gT | 이전 탭으로 이동 |
2gt | 2번 탭으로 이동 |
:tabclose | 현재 탭 닫기 |
:tabonly | 다른 모든 탭 닫기 |
:tabs | 탭 목록 표시 |
매크로는 일련의 키 입력을 기록하여 반복 실행하는 기능이다.
| 키 | 동작 |
|---|
q{a-z} | 레지스터 a~z에 매크로 기록 시작 |
q | 매크로 기록 종료 |
@{a-z} | 레지스터의 매크로 실행 |
@@ | 마지막 실행한 매크로 재실행 |
10@a | 레지스터 a의 매크로를 10회 반복 실행 |
매크로 실전 예제: CSV 각 줄의 첫 번째 필드에 따옴표 추가
원본: hello,world
목표: "hello",world
1. q a (레지스터 a에 기록 시작)
2. 0 (줄 시작으로 이동)
3. i"<Esc> (줄 앞에 " 삽입)
4. f, (첫 번째 , 앞으로 이동)
5. i"<Esc> (, 앞에 " 삽입)
6. j (다음 줄로 이동)
7. q (기록 종료)
8. 99@a (나머지 줄에 반복 적용)
| 레지스터 | 설명 |
|---|
" (unnamed) | 기본 레지스터. 삭제/복사 시 자동 사용 |
0 | 마지막 yank(복사) 내용 |
1~9 | 최근 삭제/변경 내용 (순환) |
a~z | 사용자 지정 레지스터 |
A~Z | 소문자 레지스터에 추가(append) |
+ | 시스템 클립보드 |
* | Primary selection (Linux X11) |
_ | Black hole 레지스터 (삭제해도 레지스터 오염 없음) |
% | 현재 파일명 |
: | 마지막 실행한 명령 |
/ | 마지막 검색 패턴 |
레지스터 사용 예시:
"+yy " 현재 줄을 시스템 클립보드에 복사
"+p " 시스템 클립보드 내용 붙여넣기
"_dd " 줄을 삭제하되 레지스터를 오염시키지 않음
"ayy " 레지스터 a에 현재 줄 복사
"Ayy " 레지스터 a에 현재 줄을 추가(append)
:reg
:reg a
set nocompatible
set encoding=utf-8
set fileencoding=utf-8
set number
set relativenumber
set cursorline
set showmatch
set nowrap
set scrolloff=8
set signcolumn=yes
set hlsearch
set incsearch
set ignorecase
set smartcase
set tabstop=4
set shiftwidth=4
set softtabstop=4
set expandtab
set autoindent
set smartindent
set lazyredraw
set updatetime=250
set timeoutlen=300
set hidden
set history=1000
set undolevels=1000
filetype plugin indent on
syntax on
set background=dark
set clipboard=unnamedplus
" set clipboard=unnamed " macOS
set nobackup
set nowritebackup
set noswapfile
set laststatus=2
set ruler
set showcmd
set mouse=a
let mapleader = " "
nnoremap <Leader>w :w<CR>
nnoremap <Leader>q :q<CR>
nnoremap <Leader>wq :wq<CR>
nnoremap <Leader>ev :e ~/.vimrc<CR>
nnoremap <Leader>/ :nohlsearch<CR>
nnoremap <C-h> <C-w>h
nnoremap <C-j> <C-w>j
nnoremap <C-k> <C-w>k
nnoremap <C-l> <C-w>l
nnoremap <A-j> :m .+1<CR>==
nnoremap <A-k> :m .-2<CR>==
vnoremap <A-j> :m '>+1<CR>gv=gv
vnoremap <A-k> :m '<-2<CR>gv=gv
vnoremap < <gv
vnoremap > >gv
tnoremap <Esc> <C-\><C-n>
nnoremap Y y$
nnoremap n nzzzv
nnoremap N Nzzzv
xnoremap <Leader>p
nnoremap <Leader>bn :bnext<CR>
nnoremap <Leader>bp :bprevious<CR>
nnoremap <Leader>bd :bdelete<CR>
curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
curl -fLo ~/.local/share/nvim/site/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
call plug#begin('~/.vim/plugged')
Plug 'preservim/nerdtree'
Plug 'junegunn/fzf', { 'do': { -> fzf#install() } }
Plug 'junegunn/fzf.vim'
Plug 'neoclide/coc.nvim', {'branch': 'release'}
Plug 'vim-airline/vim-airline'
Plug 'vim-airline/vim-airline-themes'
Plug 'tpope/vim-fugitive'
Plug 'tpope/vim-surround'
Plug 'tpope/vim-commentary'
Plug 'airblade/vim-gitgutter'
Plug 'morhetz/gruvbox'
call plug#end()
| 플러그인 | 기능 | 핵심 명령 |
|---|
| NERDTree | 파일 트리 탐색기 | :NERDTreeToggle (<C-n>) |
| fzf.vim | 퍼지 파일/내용 검색 | :Files, :Rg, :Buffers |
| coc.nvim | LSP, 자동완성, 진단 | gd (정의 이동), K (문서) |
| vim-surround | 괄호/따옴표 감싸기/변경 | cs"', ds", ysiw" |
| vim-commentary | 주석 토글 | gcc (줄), gc (Visual) |
| vim-fugitive | Git 통합 | :G, :Gblame, :Gdiff |
| vim-gitgutter | 변경 사항 gutter 표시 | ]c / [c (hunk 이동) |
| vim-airline | 강화된 상태바 | 자동 활성화 |
| gruvbox | 레트로 컬러 테마 | colorscheme gruvbox |
cs"' → "Hello" 를 'Hello'로 변경 (change surrounding)
cs({ → (Hello) 를 { Hello }로 변경
ds" → "Hello" 의 따옴표 제거 (delete surrounding)
ysiw" → 커서 아래 단어에 "" 추가 (you surround inner word)
yss) → 현재 줄 전체를 ()로 감싸기
S" → Visual 선택 영역을 ""로 감싸기
Neovim은 Vim과 호환되면서도 다음 장점을 제공한다.
| 기능 | Vim | Neovim |
|---|
| 설정 언어 | Vimscript | Vimscript + Lua |
| 내장 LSP | 없음 (플러그인 필요) | 내장 지원 |
| 비동기 API | 제한적 | 완전한 비동기 |
| Treesitter | 없음 | 내장 지원 |
| 설정 파일 | ~/.vimrc | ~/.config/nvim/init.lua |
| 추천 배포판 | — | LazyVim, AstroNvim, NvChad |
brew install neovim
sudo apt install neovim
sudo dnf install neovim
git clone https://github.com/LazyVim/starter ~/.config/nvim
| 카테고리 | 명령 | 설명 |
|---|
| 탈출 | <Esc> | Normal Mode로 복귀 |
| 저장/종료 | :wq | 저장 후 종료 |
| 강제 종료 | :q! | 변경 무시 종료 |
| 이동 | gg / G | 파일 시작 / 끝 |
| 이동 | /pattern | 검색 |
| 이동 | n / N | 다음/이전 검색 |
| 편집 | dd | 줄 삭제 |
| 편집 | yy | 줄 복사 |
| 편집 | p | 붙여넣기 |
| 편집 | u | Undo |
| 편집 | <C-r> | Redo |
| 편집 | ciw | 단어 변경 |
| 모드 | v / V / <C-v> | Visual 모드 |
| 창 | <C-w>s / <C-w>v | 분할 |
| 치환 | :%s/old/new/g | 전체 치환 |
{횟수}{operator}{motion 또는 text object}
예시:
3dd → 3줄 삭제
2yy → 2줄 복사
d3w → 단어 3개 삭제
ci" → 따옴표 안 내용 변경
da( → 괄호 포함 삭제
>ip → 단락 들여쓰기
| 키 | 동작 |
|---|
<C-w> | 이전 단어 삭제 |
<C-u> | 줄 시작까지 삭제 |
<C-h> | 한 글자 삭제 (Backspace) |
<C-t> | 들여쓰기 추가 |
<C-d> | 들여쓰기 제거 |
<C-r>{reg} | 레지스터 내용 삽입 |
<C-r>= | 수식 결과 삽입 (예: <C-r>=2+2<CR> → 4) |
<C-o>{cmd} | Normal Mode 명령 한 번 실행 후 Insert Mode 복귀 |
12.4 Command Mode 필수 패턴
| 명령 | 설명 |
|---|
:%s/\n/,/g | 줄바꿈을 쉼표로 치환 |
:%s/^\s*$\n//g | 빈 줄 제거 |
:%s/\s\+$//e | 줄 끝 공백 제거 |
:%!sort | 파일 전체 정렬 |
:%!sort -u | 파일 전체 정렬 후 중복 제거 |
:g/pattern/d | pattern이 있는 줄 삭제 |
:v/pattern/d | pattern이 없는 줄 삭제 (inverse) |
:g/pattern/y A | pattern이 있는 모든 줄을 레지스터 A에 복사 |
이 포스트에서 다룬 명령어들은 :help {command} 로 Vim 안에서 언제든 상세 문서를 확인할 수 있다. 예: :help text-objects, :help registers, :help macros