가장 보편적으로 사용되는 편집기인 vim 에 대해 설명한다. 기본적인 사용법은 숙지하고 있다는 전제하에 좀 더 편하고 효율적으로 사용하는 방법을 소개한다.
현재 최종 설정 파일
현재 내가 사용하고 있는 vim 의 환경 파일이라고 할 수 있는 .vimrc 파일이다.
이 파일의 위치는 ~/.vimrc 이다.
syntax on set tabstop=4 set shiftwidth=4 set softtabstop=4 set visualbell set nobackup set cindent set autoindent set smartindent set incsearch set number set visualbell filetype on set backspace=eol,start,indent set history=1000 set hlsearch set ignorecase set showmatch colo slate
syntax on
구문 강조 기능이다. 이 옵션을 설정하면 스크립트의 쉘 구문들마다 다른 색상으로 표시해주기 때문에 프로그래밍 오류를 쉽게 찾아낼 수 있다. 더불어 보기에도 좋다. 이 기능을 사용하기 위해서는 vim 편집기의 풀 버전이 설치되어 있어야 한다. 또한 작성중인 파일이 쉘 스크립트 파일이라는 것을 알리기 위해 shebang 이 반드시 존재해야 한다.
만약 :syntax on 옵션 사용에 문제가 있으면 :set syntax=sh 옵션을 사용해보길 바란다.
set hlsearch
검색 결과를 강조하여 표시해준다. echo 라는 단어를 검색할 때 사용하면 검색된 단어가 모두 하이라이트 된다.
set tabstop=4
탭 간격을 지정한다. 기본값은 8로 되어 있고 이 값을 4(주로 4를 사용)로 지정하면 긴 내용이라도 화면에 더 적합하게 표시된다.
set autoindent
자동 들여쓰기 기능으로 vim 편집기에서 직전에 입력한 줄과 같은 간격으로 새 줄 들여쓰기가 된다. 이 기능으로 많은 프로그래밍 작업 시에 입력 속도를 높일 수 있다.
Plug-in
기본적인 편집 기능 외에도 기능을 확장시켜주는 여러가지 Plug-in 들이 제공된다. 이는 vim 홈페이지에서 다운 받을 수 있다. 설치 방법은 ~/.vim 디렉토리 아래에 압축을 풀면 된다.
현재 사용하고 있는 Plug-in 은 다음과 같다.
- netdtree
- taglist
- snipMate
Tip
템플릿 사용하기
소스코드 파일을 처음 작성하다보면 동일하게 입력해야 하는 주석들이 있다. 이를 템플릿으로 만들어 일일이 입력하거나 복사하지 않고 자동으로 읽어들이게 하는 방법이 있다.
이제 템플릿 파일을 하나 만들자. 내용은 아래와 같이 한다.
<? phpinfo(); ?>
파일이름은 template.php 다. 이것을 ~/.vim 아래에 복사한다. 그리고 .vimrc 파일에 다음을 추가한다.
autocmd BufNewFile *.php 0r ~/.vim/template.php
위의 의미는 확장자가 php 로 끝나는 파일을 처음 생성할 경우, 앞서 만든 템플릿 파일을 읽어 들이겠다는 것이다. 기존의 php 파일을 읽어들일 때는 적용되지 않지만, 기존의 없는 새로운 파일을 생성해서 편집할 때는 위의 옵션이 적용된다.
새로운 파일(ex : test.php)을 만들어 확인해보자!
약어 사용하기
자주 사용되는 명령어를 짧게 약어로 사용할 수 있다. 앞에서 언급한 Plug-in 인 snipMate 를 설치하면 사용할 수 있는데, 편집하는 파일의 확장자에 따라 각기 다른 약어를 사용할 수 있다. 약어들은 보통 함수나 명령어(if, for, while 등)다.
~/.vim/snippets 디렉토리 아래에 가면, 각 확장자에 따른 설정 파일들이 존재한다. 여기서는 c 코드 작성시 사용할 약어를 추가해보겠다(c.snippets). 참고로 확장자에 상관없이 설정하기 위해서는 _.snippets 파일에 추가하면 된다.
기존의 설정에 주석을 추가했다.
... # Function snippet fun /** # 주석 추가 시작 * To handle the state, NSU_STATE_HTTP_IDLE * * @param pMsg [IN] pointer of the message to be handled * @param pStatus [IN] status of the state machine * @return next state of the state machine * @see none * @author Woojong Kim (realizeadream81@gmail.com) */ # 주석 추가 끝 ${1:void} ${2:function_name}(${3}) { ${4:/* code */} } # Function Declaration ... # Struct snippet st /** # 주석 추가 시작 * The data structure for the state machine. */ # 주석 추가 끝 struct ${1:`Filename('$1_t', 'name')`} { ${2:/* data */} }${3: /* optional variable list */};${4} # Typedef struct snippet tds /** # 주석 추가 시작 * The data structure for the state machine. */ # 주석 추가 끝 typedef struct ${2:_$1 }{ ${3:/* data */} } ${1:`Filename('$1_t', 'name')`}; # Typdef enum snippet tde /** # 주석 추가 시작 * The data structure for the state machine. */ # 주석 추가 끝 typedef enum { ${1:/* data */} } ${2:foo}; ...
설정 끄기
.vimrc 파일에 설정한 옵션 중에서 도중에 끄고 싶을 때가 있다.
이때는 앞에 no 를 붙여주면 된다.
:set nonumber # 줄번호를 출력을 끈다
편집한 파일 이동하기
여러개의 파일을 오가며, 편집하다보면, 기존에 편집했던 파일로 돌아가야할 때가 있다. 이때 사용할 수 있는 것이 b(buffer) 명령어다.
:ls // 현재까지 작업했던 파일들의 히스토리를 보여준다 :bn // 다음 버퍼에 있는 파일로 이동한다 :bp // 이전 버퍼에 있는 파일로 이동한다 :ball // 현재 버퍼의 파일을 모두 보여준다
이를 활용하여 설정 파일(.vimrc) 에 추가하자!
map <F5> : bn<CR> map <F6> : bp<CR>
F5, F6 키에 각각 매핑했다.
파일 비교 하기
두 파일의 내용을 비교할 때, 가장 많이 사용하는 것이 diff 이다. 하지만, diff 는 변경된 내용만 보여주고, 자칫 익숙하지 않은 사용자에게 있어서는 한 눈에 알아보기 어렵다는 점이 있다.
나는 개인적으로 윈도우에서는 토탈 커맨드(Total Commander) 라는 프로그램을 이 용도로 많이 사용했다. 구글링해본 결과, 리눅스에서도 이와 비슷한 프로그램을 찾을 수 있었다.
vimdiff
vim 이 설치되어있다면, 사용할 수 있다. 실행방법은 다음과 같다.
#vimdiff a b 또는 #vi -d a b
일반 콘솔 창에서도 가볍게 사용할 수 있다는 점이 특징이다.
meld
앞서 말한 윈도우에서의 Total Commander 와 유사한 인터페이스를 가진 프로그램이다. X 윈도우에서 실행되기 때문에, 사전에 설치되어 있어야 한다.
vimdiff 에 비해 두 파일의 비교점을 좀더 시각적으로 알기쉽게 보여준다.
자주 사용하는 키 모음
vim 에서 지원하는 키는 무척 많다. 하지만 이 중에서 자주 사용하는 키는 몇 안된다. 다음 표는 이들 키에 대한 설명인데, 이것들만 완전히 손에 익혀도 즐거운 컴퓨팅을 할 수 있다.
키 | 설명 |
gg | 파일의 가장 첫 줄로 이동 |
G | 파일의 가장 마지막 줄로 이동 |
dw | 커서가 위치한 한 단어를 삭제(커서를 단어의 첫 글자에 위치시킨다) |
yw | 커서가 위치한 한 단어를 버퍼에 복사한다(커서를 단어의 첫 글자에 위치시킨다) |
Ctrl + v | 비주얼모드로 사각형의 블럭을 자유자재로 지정할 수 있다 |
qa | 여러개의 창 한번에 종료하기 |
ctags 관련
ctags 와 연동하여 사용될 때, 자주 사용하는 키들은 다른 문서를 참고한다.
좀더 ctags 를 편하게 사용하기 위해 ~/.vimrc 파일에 다음을 추가한다.
if version >= 500 func! Sts( ) let st = expand("<cword>") exe "sts ".st endfunc nmap ,st :call Sts( )<cr> func! Tj( ) let st = expand("<cword>") exe "tj ".st endfunc nmap ,tj :call Tj( )<cr> endif
일반적으로 소스코드에서 찾고 싶은 심볼에 커서를 두고 'Ctrl + ]' 를 사용하여 해당 함수나 구조체로 이동한다. 선언이 한 군데만 있다면, 나름 유용한 방법이다. 하지만, 각 아키텍쳐별로 동일한 심볼로 선언이 되어있다면, 한번에 찾기는 어려울 것이다.
이럴 때, 위 설정이 도움이 된다.
커서를 심볼에 두고 ',st' 를 입력한다. 그럼 화면 아래에 찾은 리스트가 출력되는데, 이 중에서 번호를 선택하여 이동이 가능하다. 이 기능을 사용하다보면, 화면이 여러 개의 창으로 분할되어 코드 보기가 어려울 수 있다. 이럴때는 'Ctrl + w + _' 를 입력하면 현재 보고 있는 창이 넓어진다.
cscope 관련
cscope 의 사용을 쉽게하기 위해 'mkcscope.sh' 파일을 만든다.
#!/bin/sh rm -rf cscope.files cscope.files find . \( -name '*.c' -o -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.s' -o -name '*.S' \) -print > cscope.files cscope -i cscope.files
그리고 실행하기 위해 설정을 한다.
#chmod 755 mkcscope.sh #mv mkcscope.sh /usr/local/bin
소스코드의 가장 최상위 디렉토리에 가서 'mkcscope.sh' 를 실행한다. cscope.out 의 빌드가 끝나면, 'Ctrl + d' 키를 눌러 빠져나온다.
cscope 의 사용을 쉽게하기 위해 ~/.vimrc 파일에 다음을 추가한다.
set csprg=/usr/bin/cscope set nocsverb cs add /root/linux-3.8.1/cscope.out # cscope.out 파일의 경로 set csverb set csto=0 set cst func! Css() let css = expand("<cword>") new exe "cs find s ".css if getline(1) == " " exe "q!" endif endfunc nmap ,css : call Css()<cr> func! Csc() let csc = expand("<cword>") new exe "cs find c ".csc if getline(1) == " " exe "q!" endif endfunc nmap ,csc :call Csc()<cr> func! Csd() let csd = expand("<cword>") new exe "cs find d ".csd if getline(1) == " " exe "q!" endif endfunc nmap ,csd : call Csd()<cr> func! Csg() let csg = expand("<cword>") new exe "cs find g ".csg if getline(1) == " " exe "q!" endif endfunc nmap ,csg :call Csg()<cr>
위의 설정을 추가하고, 찾고 싶은 심볼에 커서를 두고, 각각 ',css ,csc ,csd ,csg' 를 입력하면, 심볼이 사용되었거나, 정의되었거나 호출한 함수들을 찾아볼 수 있다.
자주 사용하는 명령어는 다른 문서를 참고한다.
man page 사용하기
코드를 보다가 표준 C 라이브러리 함수를 모른다면, man 페이지를 이용할 수 있다. ~/.vimrc 파일에 다음을 추가한다.
func! Man() let sm = expand("<cword>") exe "!man -S 2:3:4:5:6:7:8:9:tcl:n:l:p:o ".sm endfunc nmap ,ma :call Man()<cr><cr>
모르는 함수에 커서를 두고 ',ma' 를 입력한다.
빠른 괄호 이동 및 빠른 탐색
긴 함수의 경우 if 문과 while 문이 중첩 사용되면 함수의 범위나 if 문과 while 문의 범위가 어디까지인지 잊어버리는 수가 있다. 이때는 범위를 알고 싶은 '{' 또는 '}' 기호에서 % 기호를 누르면 쌍을 이루는 '{' 또는 '}' 로 커서가 이동한다.
여러 행 탭(tab) 끼워 넣기
여러 행의 앞부분에 탭을 일괄적으로 끼우거나 제거해야 될 때가 의외로 자주 발생한다. 이럴때는 여러행을 블록으로 선택한 후에 '> 키 또는 < 키' 를 입력한다.
흐트러진 소스 정렬
간혹 소스를 마우스로 드래그해서 복사한 후 붙여넣었다면, 소스가 흐트러지는 현상이 발생한다.
이럴때는 블록을 지정하고, '=' 을 입력하면 된다.
자동완성 기능 사용하기
함수나 변수의 일부만을 타이핑하고 'Ctrl + p 나 Ctrl + n' 키를 누르면 자동 완성 기능을 사용할 수 있다. 매우 긴 함수나 변수를 일일이 타이핑하지 않아도 되므로 자동 완성 기능은 유용할 때가 많다.
헤더 파일 바로 읽어오기
소스코드의 헤더 파일명에 커서를 위치시키고 'Ctrl + wf' 키를 누르면 창이 수평 분할 되면서 헤더파일이 열린다. 이때 path 변수에 경로를 지정하면 지정한 경로를 기준으로 헤더파일을 찾는다. 그래서 ~/.vimrc 파일에 다음과 같은 명령을 추가하면 vim 은 헤더파일을 /usr/include 부터 /work/include 까지 찾는다.
set path=/usr/include:/work/include
Source insight 처럼 사용하기
윈도우에서 자주 사용하는 소스 인사이트를 vim 으로도 비슷하게 사용할 수 있다.
먼저 기본이 되는 vim, ctags, cscope 를 설치해야 한다. 준비가 되었으면, 이제 스크립트들을 설치해야한다. 여기서 필요한 것들은 다음과 같다.
- http://www.vim.org/scripts/script.php?script_id=2179 Source Explorer
각각의 스크립트들을 다운받았으면, ~/.vim 디렉토리 아래로 옮긴다.
#mv SrcExpl-5.1.zip nerdtree.zip taglist_46.zip ~/.vim/
설치를 위해 압축을 푼다.
#unzip SrcExpl-5.1.zip #unzip nerdtree.zip #unzip taglist_46.zip #cp SrcExpl/plugin/srcexpl.vim plugin/
plugin 디렉토리에 아래와 같이 3개의 스크립트 파일이 들어있는지 확인한다.
#cd plugin && ls NERD_tree.vim srcexpl.vim taglist.vim
설치가 완료되었다. 이제 실제 제대로 동작하는지 확인하기 위해 리눅스 커널을 다운받는다.
#mv linux-3.8.1.tar.bz2 /root/ #tar xjf linux-3.8.1.tar.bz2 #cd linux-3.8.1 #ctags -R // ctags 를 위한 DB 생성 #mkcscope.sh // cscope 를 위한 DB 생성
이제 설정파일을 작성할 차례다.
syntax on set tabstop=4 set shiftwidth=4 set expandtab set softtabstop=4 set visualbell set nobackup set cindent set autoindent set smartindent set incsearch set number set visualbell filetype on set backspace=eol,start,indent set history=1000 set hlsearch set ignorecase set showmatch colo slate set paste set bg=dark set tags=/root/linux-3.8.1/tags "tags 파일 위치 지정" set path=/usr/include,/usr/local/include,/usr/src/include,/root/linux-3.8.1/include "헤더파일을 찾을 때 사용할 경로 지정" "=============== Cscope ==============" set csprg=/usr/bin/cscope set nocsverb cs add /root/linux-3.8.1/cscope.out /root/linux-3.8.1 "cscope DB 파일 경로를 지정하고, 소스코드의 최상위 경로를 지정해야 한다 " set csverb set csto=0 set cst func! Css() let css = expand("<cword>") new exe "cs find s ".css if getline(1) == " " exe "q!" endif endfunc nmap ,css :call Css()<cr> func! Csc() let csc = expand("<cword>") new exe "cs find c ".csc if getline(1) == " " exe "q!" endif endfunc nmap ,csc :call Csc()<cr> func! Csd() let csd = expand("<cword>") new exe "cs find d ".csd if getline(1) == " " exe "q!" endif endfunc nmap ,csd :call Csd()<cr> func! Csg() let csg = expand("<cword>") new exe "cs find g ".csg if getline(1) == " " exe "q!" endif endfunc nmap ,csg :call Csg()<cr> "=============== Manpage ==============" func! Man() let sm = expand("<cword>") exe "!man -S 2:3:4:5:6:7:8:9:tcl:n:l:p:o ".sm endfunc nmap ,ma :call Man()<cr><cr> "=============== Taglist ==============" nmap <F7> :TlistToggle <bar> NERDTreeToggle <bar> SrcExplToggle<CR> let Tlist_Ctags_Cmd = "/usr/bin/ctags" let Tlist_Inc_Winwidth = 0 let Tlist_Exit_OnlyWindow = 0 let Tlist_Auto_Open = 0 let Tlist_Use_Left_Window = 1 "=============== NERDTree ==============" let NERDTreeWinPos = "right" "=============== Source Explorer ==============" nmap <C-H> <C-W>h nmap <C-J> <C-W>j nmap <C-K> <C-W>k nmap <C-L> <C-W>l let g:SrcExpl_winHeight = 8 let g:SrcExpl_refreshTime = 100 let g:SrcExpl_jumpKey = "<ENTER>" let g:SrcExpl_gobackKey = "<SPACE>" let g:SrcExpl_isUpdateTags = 0
사용해보기
vi 를 실행하고, F7 키를 누르면, 창이 분할 되면서 마치 source insight 와 같은 모습이 보일 것이다. ctags 의 부족한 기능을 매우기 위해, 사용하는 cscope 는 일반모드에서 알고싶은 심볼에 커서를 두고 ',css' 를 입력하면, 해당 심볼이 사용된 목록을 보여준다. 번호를 입력하면, 해당 코드로 이동하게 된다.
위 .vimrc 설정에서 유의할 점은 각 항목들에 대한 경로이다. 경로가 맞지 않으면, 심볼을 찾지 못하는 에러가 발생한다.
자동으로 tags, cscope 파일 만들기
새로운 소스코드를 분석하기 위해서는 앞서 살펴본 바와 같이 ctags 와 cscope 를 사용하여 심볼 파일을 만들고, 이를 vim 에서 인식하도록 설정파일에 추가해주어야 한다.
매번 이렇게 작업을 한다는 것은 상당히 번거로운 일이며, 이를 자동화하기 위해 아래와 같이 스크립트 파일을 만들었다. 파일 이름은 'addproject' 이다.
#!/bin/bash ctags -R sleep 1 mkcscope.sh sleep 1 echo "set tags=$PWD/tags" >> ~/.vimrc echo "cs add $PWD/cscope.out $PWD" >> ~/.vimrc
사용 방법은 소스코드의 가장 최상위 디렉토리로 이동하여 실행하면 된다.
#cd /usr/src/linux-3.6.1 #addproject
실행이 완료되면, tags 와 cscope 관련파일이 생성되며, .vimrc 파일에 추가된다.