Section 01버퍼-로컬 매핑과 옵션
매핑·약어·옵션을 한 번에 하나의 버퍼에만 설정할 수 있습니다. 이 아이디어의 진정한 힘은 자동명령과 결합할 때 드러납니다.
두 파일 foo, bar를 각각 분할로 열어 둔 채로, foo에서 다음을 실행하세요:
:nnoremap <leader>d dd :nnoremap <buffer> <localleader>x dd
foo에서는 두 매핑 모두 작동합니다. 하지만 bar로 옮겨가 <localleader>x를 누르면 — 전체 줄 대신 문자 하나만 삭제됩니다! <buffer>가 그 매핑을 "정의한 버퍼에서만" 적용되게 했기 때문입니다.
버퍼-로컬 옵션
일부 옵션은 버퍼마다 따로 설정할 수 있습니다. setlocal을 씁니다:
:setlocal wrap " 이 버퍼만 줄바꿈 :setlocal number " 이 버퍼만 줄 번호
<leader>가 아니라 <localleader>를 쓰세요. 두 개의 별도 리더 키가 일종의 "네임스페이싱"을 제공해, 전역 매핑과 파일타입별 매핑을 머릿속에서 깔끔하게 구분하게 해줍니다. 더 구체적인(버퍼-로컬) 매핑이 전역 매핑보다 우선합니다.
Section 02자동명령의 구조
자동명령(autocommand)은 특정 이벤트가 발생할 때마다 Vim이 명령을 실행하게 하는 방법입니다. 예제로 바로 들어갑시다:
:autocmd BufNewFile * :write
이제 :edit foo로 새 파일을 열고 :quit로 닫으면 — 파일이 디스크에 생깁니다. 보통 Vim은 처음 저장할 때까지 파일을 실제로 만들지 않지만, 이 자동명령이 새 파일을 만들자마자 저장하게 했습니다.
:autocmd BufNewFile *.txt :write는 세 부분으로 이루어집니다:
이벤트 — BufNewFile — 무엇을 감시할지.
패턴 — *.txt — 어떤 파일에만 적용할지 거르는 필터.
명령 — :write — 이벤트가 발생하면 실행할 것.
이벤트는 종류가 매우 많습니다 — 존재하지 않는 파일을 편집 시작할 때, 파일을 읽을 때, 파일타입이 바뀔 때, 입력 모드에 들어가거나 나갈 때 등. 쉼표로 여러 이벤트를 묶을 수도 있습니다:
:autocmd BufNewFile,BufRead *.html setlocal nowrap
BufRead와 BufNewFile을 함께 묶는 것은 흔한 관용구입니다 — 파일이 이미 존재하든 아니든, 특정 종류의 파일을 열 때마다 명령을 실행합니다.
<cr> 같은 특수 문자를 직접 쓸 수 없습니다. 이 제약을 우회하는 법은 8장의 execute에서 배웁니다. 지금은 이 한계를 받아들이세요.
Section 03FileType 이벤트
가장 유용한 이벤트 중 하나가 FileType입니다. Vim이 버퍼의 파일타입을 설정할 때마다 발화합니다. 버퍼-로컬 매핑과 결합하면, 편집 중인 파일의 종류에 특화된 매핑을 만들 수 있습니다:
:autocmd FileType javascript nnoremap <buffer> <localleader>c I//<esc> :autocmd FileType python nnoremap <buffer> <localleader>c I#<esc>
JavaScript 파일에서 <localleader>c를 누르면 줄이 //로 주석 처리되고, Python 파일에서는 같은 키가 #으로 주석 처리합니다. "줄의 시작으로 가서 주석 문자를 추가한다"고 생각하는 대신, 그저 "이 줄을 주석 처리한다"고만 생각하면 됩니다. 코딩 시 머리의 부담이 줄어듭니다.
Section 04자동명령 그룹
자동명령에는 골치 아픈 문제가 있습니다. 같은 자동명령을 여러 번 실행하면 — Vim은 그것을 중복으로 만듭니다:
:autocmd BufWrite * :echom "Writing buffer!" " 위 명령을 4번 실행하면, 저장 시 메시지가 4번 출력된다
~/.vimrc를 소싱하면 파일 전체가 다시 읽힙니다 — 자동명령 정의까지 포함해서. vimrc를 소싱할 때마다 자동명령이 중복으로 쌓여 Vim이 점점 느려집니다.
해결책은 관련 자동명령을 이름 있는 그룹으로 묶고, 그룹을 비운 뒤 채우는 것입니다:
augroup filetype_html autocmd! autocmd FileType html nnoremap <buffer> <localleader>f Vatzf augroup END
augroup filetype_html로 그룹에 들어가고, autocmd!로 그룹을 즉시 비우고, 자동명령을 정의한 뒤, augroup END로 그룹을 나옵니다. vimrc를 다시 소싱해도 autocmd!의 비우기 덕분에 중복이 생기지 않습니다.
augroup + autocmd! 패턴으로 감싸세요. 예외 없이. 이것이 vimrc가 느려지지 않게 하는 유일한 방법입니다.
Section 05버퍼-로컬 약어와 스니펫
버퍼-로컬 약어를 자동명령과 결합하면 작은 스니펫 시스템을 만들 수 있습니다:
:autocmd FileType python :iabbrev <buffer> iff if:<left> :autocmd FileType javascript :iabbrev <buffer> iff if ()<left>
JavaScript 파일에서 iff를 입력하면 if ()가, Python 파일에서는 if:가 펼쳐집니다. <left>는 커서를 한 칸 왼쪽으로 옮겨 괄호/콜론 안에 두게 합니다. Vim이 현재 파일 종류에 따라 적절한 약어를 수행합니다.
Section 06연습문제
:help local-options,:help setlocal,:help map-local을 읽으세요.:help autocmd-events를 훑어보고, 자동명령을 묶을 수 있는 이벤트들의 종류를 느껴 보세요. 외울 필요는 없습니다.- 좋아하는 파일타입들에 대해
setlocal로 옵션을 설정하는FileType자동명령 몇 개를 만드세요(wrap,list,spell,number등). - 자주 쓰는 파일타입들에 대해 "이 줄을 주석 처리" 자동명령을 만드세요.
~/.vimrc의 모든 자동명령을augroup+autocmd!패턴으로 감싸세요.- 특정 종류의 파일에서 자주 입력하는 것들에 대한 "스니펫" 약어를 만드세요.