Section 01플러그인 구조와 Pathogen
이 장의 플러그인은 Potion 프로그래밍 언어 지원을 추가합니다. Potion은 작은 장난감 언어라 우리 목적에 이상적입니다 — 목표는 Potion을 배우는 것이 아니라, 완전한 Vim 플러그인의 여러 측면을 작은 예제로 짚어보는 것입니다.
바닐라 Vim은 플러그인을 여러 디렉터리로 나눕니다 — colors/, plugin/, ftdetect/, ftplugin/, syntax/, indent/, autoload/, doc/ 등. 각 디렉터리는 정해진 의미를 갖습니다.
예전엔 플러그인 파일을 디렉터리마다 하나씩 흩어 놓아야 했습니다. Tim Pope의 Pathogen은 이를 단순하게 만듭니다.
~/.vim/bundle/ 안의 각 디렉터리가 runtimepath에 자동 추가됩니다. 즉, 각 플러그인이 자기만의 디렉터리에 통째로 들어갈 수 있습니다 — 업데이트는 옛 디렉터리를 지우고 새 버전으로 바꾸기만 하면 됩니다.
potion/ README LICENSE doc/ potion.txt ftdetect/ potion.vim ftplugin/ potion.vim syntax/ potion.vim autoload/ potion/running.vim
이 구조 그대로 GitHub나 Bitbucket에 올리면, 사용자는 bundle/로 클론하기만 해도 모든 것이 작동합니다.
Section 02파일타입 감지
먼저 Vim이 Potion 파일(.pn)을 알아보게 해야 합니다. ftdetect/potion.vim에 자동명령 하나를 둡니다:
au BufNewFile,BufRead *.pn set filetype=potion
이 자동명령은 .pn 파일의 파일타입을 potion으로 설정합니다. ftdetect/ 안의 파일은 Vim이 자동명령 그룹으로 자동 감싸주므로, 여기서는 augroup을 직접 쓸 필요가 없습니다. 이제 :set filetype?로 확인하면 filetype=potion이 나옵니다.
Section 03구문 강조
syntax/potion.vim에 구문 강조 코드를 둡니다. 파일은 표준 보일러플레이트로 감쌉니다:
if exists("b:current_syntax") finish endif syntax keyword potionKeyword loop times to while if elsif else syntax keyword potionFunction print join string highlight link potionKeyword Keyword highlight link potionFunction Function let b:current_syntax = "potion"
① syntax keyword(또는 syntax match, syntax region)로 구문의 "덩어리"를 정의한다.
② highlight link로 그 덩어리를 공통 강조 그룹(Keyword, Function, Comment 등)에 연결한다.
이렇게 하면 플러그인 저자는 구문을, 색 구성표 저자는 색을 각자 정의할 수 있습니다.
리터럴 키워드가 아닌 것 — 주석, 연산자, 문자열 — 은 정규표현식이 필요합니다. syntax match는 정규표현식 패턴을, syntax region은 시작·끝 패턴을 받습니다:
syntax match potionComment "\v#.*$" syntax match potionOperator "\v\*\=" syntax region potionString start=/\v"/ skip=/\v\\./ end=/\v"/ highlight link potionComment Comment highlight link potionString String
syntax match는 한 줄에 그룹 하나만 받습니다. 작은 그룹을 먼저, 큰 그룹을 나중에 정의하세요 — 그래야 -와 -= 같은 겹치는 패턴이 의도대로 매칭됩니다. region의 skip 인자는 \" 같은 문자열 이스케이프를 처리하게 해줍니다.
Section 04코드 폴딩과 섹션 이동
Vim은 코드 폴딩 방식을 여섯 가지 지원합니다 — manual, marker, diff, expr, indent. 들여쓰기 기반 폴딩은 거의 공짜입니다. ftplugin/potion/folding.vim에 한 줄이면 됩니다:
setlocal foldmethod=indent setlocal foldignore=
더 정교한 폴딩을 원하면 expr 폴딩으로 커스텀 Vimscript 함수를 씁니다. 각 줄에 "폴드 레벨"이 있고, 함수가 그것을 결정합니다:
setlocal foldmethod=expr setlocal foldexpr=GetPotionFold(v:lnum) function! GetPotionFold(lnum) if getline(a:lnum) =~? '\v^\s*$' return '-1' " 빈 줄 — 폴드 레벨 미정 endif " ... 들여쓰기 레벨을 비교해 폴드 레벨을 정한다 ... endfunction
foldexpr 함수는 폴드 레벨을 직접 반환하거나, 특수 문자열을 반환할 수 있습니다 — '-1'(미정, 이웃을 따름), '>1'(레벨 1 폴드를 연다). 같은 레벨의 인접한 줄들이 함께 접힙니다.
섹션 이동
Vim의 섹션 이동 명령([[, ]], [], ][)을 Potion 파일에 맞게 재매핑할 수 있습니다. ftplugin/potion/sections.vim에서 noremap(연산자 대기 모드에서도 작동하도록)으로 매핑하고, 공통 함수를 호출하게 합니다:
noremap <script> <buffer> <silent> ]] :call <SID>NextSection(1, 0)<cr> noremap <script> <buffer> <silent> [[ :call <SID>NextSection(1, 1)<cr>
Section 05자동로드 · 문서화 · 배포
자동로드
autoload는 플러그인 코드의 로딩을 실제로 필요할 때까지 미루는 기법입니다. 사용자가 매번 쓰지 않는 기능은 autoload/ 디렉터리로 옮겨, Vim 시작 시간에 주는 부담을 줄이세요:
function! potion#running#PotionCompileAndRunFile() silent !clear execute "!" . g:potion_command . " " . bufname("%") endfunction
함수 이름의 potion#running# 부분이 디렉터리·파일명과 일치합니다. Vim은 potion#running#X 호출을 만나면 autoload/potion/running.vim을 찾아 그때 처음 로드합니다. 매핑·명령은 사용자가 호출해야 하므로 자동로드할 수 없습니다 — 그래서 nnoremap은 ftplugin/에 남깁니다.
문서화
Vim의 도움말 파일은 그저 구문 강조된 텍스트 파일입니다 — doc/potion.txt에 직접 쓸 수 있습니다. 별표로 단어를 감싸면 점프 가능한 태그가 되고, 막대(|)로 감싸면 태그로의 링크가 됩니다:
*potion.txt* functionality for the potion programming language CONTENTS *PotionContents* 1. Usage ................ |PotionUsage| 2. Mappings ............. |PotionMappings|
:Helptags로 도움말 인덱스를 다시 만들면, 사용자는 :help potion.txt로 문서를 열 수 있습니다. 문서는 보통 Introduction, Usage, Mappings, Configuration, License, Bugs, Changelog, Credits 절로 구성합니다.
배포
플러그인을 Vim.org의 스크립트 섹션과 GitHub/Bitbucket 저장소에 올리세요. README에는 무엇을 하는 플러그인인지, 왜 써야 하는지, 라이선스, 전체 문서 링크를 담으세요. 그리고 Twitter, Reddit의 /r/vim, Vim 메일링 리스트에 알리세요.
Section 06연습문제와 그다음
:help runtimepath를 읽고, Pathogen의 소스 코드를 살펴 무슨 일이 일어나는지 확인하세요.:help syntax,:help syn-match,:help syn-region을 읽으세요.:help foldexpr,:help fold-expr를 읽고, 반환할 수 있는 특수 문자열들을 확인하세요.:help autoload,:help section을 읽으세요.:help help-writing을 읽고, 자신의 vimrc 매핑 하나를 주석으로 완전히 문서화해 보세요.
이제 무엇을 할까
이 책의 모든 예제와 연습을 마쳤다면, 이제 Vimscript의 기초를 단단히 잡았습니다. 더 배울 것은 여전히 많습니다 — 색 구성표, :command 명령, omnicomplete, 컴파일러 지원, 그리고 Python·Ruby·Lua 같은 다른 언어로 Vim을 스크립팅하는 법.
하지만 가장 중요한 마지막 연습은 이것입니다 — 당신이 늘 원했던 무언가를 위한 Vim 플러그인을 직접 쓰고, 세상과 공유하세요.