VIM 강좌 - vim 으로 폼나는 개발자가 되어보자 [출처] VIM 강좌

|
VIM 강좌 - vim 으로 폼나는 개발자가 되어보자 강좌

2004/12/03 11:17

복사 http://blog.naver.com/cain2332/40008472302

리눅스 사용 용도에 대한 많은 설문 조사를 보게 되면, 개발 플랫폼에 대한 비중도 만만치 않게 나오고 있다. 물론 그만큼 대부분의 일반사용자를 끌어 들일만한 프로그램이 없다는 뜻이기도 하지만, 반대로 개발자를 위해 더 없이 좋은 환경을 가지고 있다는 의미이기도 하다. 당연한 말이겠지만 vim 은 개발자를 통해 개발되었고, 그만큼 개발자를 위해 많은 기능들이 추가되어온 편집기이다.

4.1 Syntax Highlight 먼저 Syntax highlight 기능에 대해 알아보자.

C 언어와 같은 Programming Language 에는 변수, 상수, 키워드 등 단어 하나하나에 특별한 의미가 있다. C 언어뿐만 아니라 HTML 과 같은 Mark Up Language 에도 태그별로 특별한 의미가 있다. 이렇게 특별한 의미가 있는 단어별로 다른 색이나, 역상으로 다른 효과를 주는 것을 Syntax Highlight 이라 하고, 이 기능은 다음 명령어로 활성화 시킬 수 있다.

:syntax on
Syntax highlight을 활성화 시키게 되면 C, C++, Java, HTML, XML 과 같은 언어의 특성과 문법에 맞게 미리 지정된 색상을 보여준다.

이렇게 여러 색상을 사용하면서 텍스트 파일을 편집할 때 화면 배색이 맞지 않게 되면, 가독성도 떨어지고 눈이 쉽게 피로해지게 된다. vim 은 바탕화면이 어두운지 혹은 밝은지를 판단하여 전체적인 색상을 밝거나 어둡게 조절할 수 있다. 하지만 vim 이 배경의 밝기를 잘못 판단할 수도 있다. 다음 명령으로 vim 이 현재 터미널의 배경을 어떻게 추측하는지 알아보도록 하자.

:set background?

위와 같은 명령을 주면 현재 background 의 세팅 값을 알 수 있다. 필자의 경우 배경이 무척 어두움에도 불구하고 다음처럼 vim 은 밝은 색으로 추측하고 있다.




만약 여러분의 배경이 어둡다면 다음처럼 vim 에게 알려주면 편집하는 문자의 색을 밝게 해줄 것이다.




:set background=dark


마찬가지로 배경이 흰색처럼 밝다면 다음 명령으로 이를 지정할 수 있다.




:set background=dark




Vim 은 색상이 제대로 나오고 있는지 테스트 할 수 있는 방법을 제공하고 있다. VIM 에는 C, C++, HTML, JAVA 와 같은 다양한 언어나 형태별로 설정을 지정하는 RUNTIME 디렉토리가 있다. 이중에는 Color를 테스트 할 수 있는 파일도 있는데, 이 파일을 이용하여 색상을 테스트 해보도록 하겠다. vim을 연 상태에서 다음과 같은 명령을 입력해 보도록 하자.




:edit $VIMRUNTIME/syntax/colortest.vim

:source %




$VIMRUNTIME/syntax/colortest.vim 은 색상 테스트용 Run Time 파일이고, 그 다음 줄에서 '%' 가 가르키는 것은 이전 명령에서 첫 번째 인자를 가르킨다. 즉

:source % 는

:source $VIMRUNTIME/syntax/colortest.vim 명령과 동일하다.




vim 은 파일의 확장자를 보고 어떤 규칙을 정할지 결정을 한다. 확장자가 .html, .htm 은 HTML 문서로, .c, .h 와 같은 파일은 C 언어로 인식을 한다. C 언어의 문법에 맞게 작성한 문서라도 확장자가 없다면, C 언어에 맞게 규칙을 적용하지 않게 되는데 이런 경우




:set filetype=c




명령을 사용하게 되면 C 언어에서 사용하는 확장자가 아니더라도 C 언어의 규칙대로 Syntax Highlight를 적용할 수 있다.




4.2 들여쓰기

C 언어에서의 들여쓰기



긴 프로그램을 작성하기 위해서 가독성 높은 코딩 습관은 필수적이라 하겠다. 프로그램 코드의 가독성에 가장 중요한 요소는 바로 들여쓰기 있다. 들여쓰기는 개개인의 코딩 습관에 따라 방식이 다르지만, 위의 그림처럼 보통 함수나 조건문과 같이 새로운 블록이 생성될 때


마다

하나를 두어 새로운 블록을 감싸는 블록의 안쪽으로 코드가 보이도록 하는 게 일반적이다. 들여쓰기를 할 때 어느 정도 이동 시킬 것인지 크기는 다음과 같은 명령으로 결정한다.




:set shiftwidth=4




현재 설정된 shift 의 크기는




:set shiftwidth?




명령으로 알 수 있다.

주로 들여쓰기는 키를 이용하지만 Normal Mode에서 다음과 같은 Shift 명령을 사용 할 수 있다.




>> : 오른쪽으로 Shift

<< : 왼쪽으로 Shift

2>> : 2줄 오른쪽으로 Shift




위와 같이 Shift 명령으로 들여쓰기를 할 수도 있지만 Vim은 Auto Indent(자동 들여쓰기) 기능을 제공하여 더욱 편하게 코딩을 할 수 있도록 도와주고 있다. Vim 는 cindent, smartindent, autoindent 와 같은 세가지 타입의 자동 들여쓰기를 제공한다.




cindent




C, C++, Java 스타일의 자동 들여쓰기이다. 새로운 블록이 시작될 때 자동으로 인식하고 들여쓰기를 행하여 준다.




:set cindent




명령으로 cindent를 활성화 시킬 수 있다. 만약 C 나 JAVA 파일을 편집할 때 자동으로 cindent를 활성화 시키고 싶다면 다음과 같은 명령을 미리 $HOME/.vimrc 파일에 저장해 두는 것도 좋을 것이다.




:filetype on

:autocmd FileType c,cpp,java :set cindent





첫 번째 :filetype on 명령은 파일의 타입을 체크하고, 두 번째 명령은 C, C++, JAVA 파일 일 경우 cindent를 적용하게 하는 것이다.




smartindent




smartindent는 cindent처럼 블록이 시작하면 자동으로 들여쓰기를 해주게 된다. 하지만 cindent 에서는 #define, #ifdef 와 같이 # 으로 시작하는 전처리기에 대해서 들여쓰기를 무시하고 첫 번째 칸으로 커서를 이동시켜 주는데 반해 smartindent 는 전처리기에 대해서도 동일한 들여쓰기를 행하게 된다.




smartindent 는




:set smartindent




명령으로 활성화 시킬 수 있다. smartindent 는 cindent 만큼 똑똑하지는 않지만 다음에 설명할 autoindent 보다는 똑똑한 셈이다.




autoindent




autoindent 는 단지 줄 바꿈할 때 커서를 전 줄의 시작위치에 놓아 주기만 한다. cindent 와 smartindent 가 블록이 시작할 때 마다 자동으로 들여쓰기를 해주고, 블록이 끝나면 들여쓰기를 해제해주는데 비하면 별로 하는 일이 없는 셈이다. autoindent 는 C 나 JAVA 보다는 Python 과 같은 언어에서 사용하면 좋을 것이다.




:set autoindent




명령으로 활성화 시킬 수 있다.




=%




=% 명령을 사용하면 특정 블록에 대한 들여쓰기를 자동으로 실행할 수 있다. 일단 다음 그림처럼 블록이 시작하는 위치인 ‘{’ 에 커서를 위치 시킨 후 ‘=%’ 명령을 실행해보자! 그럼 다음 그림처럼 자동으로 들여쓰기가 행해진 것을 알 수 있다.






% 는 ( ), { }, [ ] 와 같은 괄호 한쪽 끝에서 다른 한쪽 끝으로 이동하는 명령이다. =%처럼 들여쓰기에도 사용할 수 있고 다음과 같이 d% 명령으로 괄호 내의 모든 내용을 삭제 할 수도 있다.






>%과 <%명령은 { }를 포함하여 블록내의 내용을 각각 오른쪽 및 왼쪽으로 shift 시킨다. 커서를 블록의 시작인 { 에 놓고 >%과 <%명령을 실행하면 블록의 끝인 } 까지 모든 내용을 shift 시킬 것이다. 만약 { } 은 남겨두고 내용만 옮기고 싶다면 커서를 { 에 두고 >i}혹은















만약 Visual Mode를 사용한다면 원하는 구간을 Visual Block 으로 잡고 바로 Shift 명령을 내려주면 된다.




4.3 변수, 매크로 찾기




프로그램을 작성하다 보면 변수나 매크로를 빈번하게 정의하게 된다. 변수나 매크로가 하나 둘 늘어나다 보면 어디에 변수 정의 부분이 있는지 찾기 힘든 경우가 있다. 물론 매크로도 마찬가지로 매크로에 해당하는 값을 잊어버려 당황하는 경우가 종종 있을 것이다. vim은 비록 완벽하진 않지만, 변수나 매크로의 정의를 찾아내기 편리한 명령을 제공하고 있다.


위의 그림에서 va_global 의 정의 부분을 알기 위해 printf() 함수 내의 va_global 에 커서를 올려 놓고 gd 명령을 내리면 최근 va_global 의 대입문으로 커서가 이동한다. gD 명령을 이용하면 위의 화살표처럼 곧장 va_global의 선언부로 커서가 이동할 것이다. 만약 hlsearch 가 세팅되어 있다면 모든 va_global 이 역상으로 표시 되고 n, N 과 같은 검색관련 명령도 적용이 가능하다.




비슷하게 [d명령은 가장 처음 매크로를 정의한 부분을 화면 하단에 보여준다.




[d 대신 ]d를 사용하면 커서 이후에서 정의를 찾게 된다. 만약 정의 내역이 없다면 아래와 같이 정의를 찾을 수 없다는 메시지가 출력된다.

매크로를 찾을 수 없을 경우



[D명령은 여러번 정의 될 경우 그 리스트를 아래와 같이 보여준다.

[D 명령으로 매크로 리스트 확인



4.4 매뉴얼 보기




프로그램을 작성하다 보면 함수에 대한 레퍼런스 매뉴얼을 참조해야 할 경우가 있다. 매뉴얼을 참조하기 위해 편집하던 Vim을 빠져나가 man 이라는 Unix 명령을 내릴 수도 있지만



Vim에서는 더욱 간단한 방법을 제공하고 있다. 편집 도중 원하는 함수에 커서를 두고 K명령을 내리면 바로 man 페이지를 보여주게 된다. 만약 mkdir 이라는 함수에 커서를 올려 놓고 K 명령을 내리면 vim 은 자동으로 man mkdir을 실행한 후 결과를 화면에 보여주게 되는 것이다. 이러한 경우 man 페이지의 특징상 개발자 가이드가 아닌 시스템 명령어를 출력할 수도 있다. 만약 다른 매뉴얼이 아니라 개발자 매뉴얼을 보이게 하고 싶다면 그냥 K가 아닌 2K명령을 내려보기 바란다. 그러면 vim 은 내부적으로 man 2 mkdir 을 실행할 것이다.




4.5 Tag




C 나 C++ 와 같은 언어에서는 빈번하게 함수 호출이 이루어진다. 대부분의 경우 함수에 대한 설명만으로 함수에 대해 이해한 뒤 호출을 하지만, 디버그를 위해서나 여러 가지 이유로 함수의 정의 자체가 궁금할 수도 있을 것이다. 함수의 내용이 지금 편집하고 있는 파일 내에 있다면 바로 검색해서 볼 수도 있겠지만 만약 다른 파일에 있다면 다른 파일을 열어 검색해야 하는 불편함이 있을 것이다. 지금 어느 정도 조금씩 느껴갈 것이라 예상하지만, 리눅스에서는 값비싼 통합환경이 부럽지 않을 만큼 다양한 툴을 무료로 제공하고 있다. 그 중 하나 ctags 는 다양한 언어에 대한 태그 파일을 생성해주는 툴이다.

커맨드 라인에서




$ ctags *.c




라는 명령을 내려주면 현재 디렉토리 내에 tags 라는 태그 파일을 생성해 준다. 태그파일 내에는 함수들이 어느 파일의 어느 위치에 있는지 정보가 담겨 있다고 이해하면 될 것이다. ctags 는 리눅스 배포본의 ctags 라는 이름의 패키지에 담겨 있다. ctags 는 C 언어뿐만 아니라, JAVA, C++, PHP, Fortran, List, ASP, COBOL 과 같이 널리 알려있는 대부분의 언어를 지원한다.




자 이제 vim 에서는 이 태그 파일을 어떻게 활용하는지 알아보도록 하자. 이미 ctags 명령어를 통해 tags 파일을 만들었다는 가정 하에 다음 그림처럼 addrtot() 라는 함수 위에 커서를 올려 놓은 후 Ctrl+]명령을 내려보자. Ctrl+]명령을 내리면 바로 그 함수의 정의 부분으로 화면이 전환된다.










위의 그림을 보면 subnettot.c 라는 파일을 편집하던 도중 Ctrl+] 명령으로 addrtot.c 라는 파일로 전환된 것을 볼 수 있을 것이다. 파일이 전환된 상태에서 다시 이전 위치로 커서를 이동시키고자 한다면 Ctrl+T명령을 내리면 된다. 이전 위치로 이동한 상태에서 다시 addrtot() 함수가 있던 곳으로 커서를 이동 시키려면 :tag명령을 주고 를 쳐주면 된다.




위의 2번째 화면에 addrtot_again() 이라는 함수를 호출하는 부분이 있다고 해보자. 그 위치에서 Ctrl+]명령을 주면 addrtot_again() 함수가 정의되어 있는 곳으로 이동하게 될 것이다. addrtot_again() 함수가 정의되어 있는 곳에서 Ctrl+T명령을 주게되면 위의 그림에서 2번째 화면으로, 다시 한번 Ctrl+T명령을 주면 첫 번째 화면으로 이동하게 된다.




Ctrl+T 명령으로 첫 화면으로 이동한 상태에서 :2tag명령을 내린 뒤 를 쳐주게 되면 addrtot_again() 함수가 정의되어 있는 곳으로 2단계를 뛰어서 이동한다. :2tag 와 비슷하게 2Ctrl+T역시 2단계 전으로 이동할 수 있다.




지금까지 vim 으로 검색한 태그 목록은 :tags명령으로 확인 할 수 있다.





:tags 명령으로 태그 리스트 확인







:tag <태그> 명령으로 화면 전환



:tag <태그> 명령을 내리면 위와 같이 함수의 정의 부분으로 편집 화면이 전환 된다. 지금까지 명령어의 변화를 감지한 독자라면 화면을 분할하며 함수의 정의 부분으로 이동하는 명령을 쉽게 눈치 챌 수 있을 것이다.



:stag <태그> 명령으로 화면을 분할





:stag <태그> 명령은 위와 같이 화면을 상하로 분할하며 함수의 정의 부분을 분할된 창에 보여준다. 이 상태에서 전 강좌에서 다룬 분할된 창에서의 명령을 모두 사용할 수 있다.




:tag <태그> 명령을 내려보다 보면 <태그> 에 해당되는 내용을 vim 이 검색한다는 것을 알 수 있다. vim을 포함한 모든 유닉스에서 정규표현식을 이용하면 검색 기능에 날개를 달 수 있다. <태그>에 정규표현식을 사용하고 싶을 때는 <태그>앞에 ‘/’를 추가해 주면 된다.




:tag /<정규표현식을 사용한 태그>




예를 들어




:tag /^addr




명령을 내리게 되면 "addr" 이라는 문자열로 시작하는 함수의 정의 부분으로 커서가 이동하게 된다. 하지만 정규표현식을 통해 검색하게 되면 검색 결과가 하나 이상이 될 수 있다. 기본적으로 위의 명령을 내리면 addr 로 시작하는 첫 번째 함수로 이동하게 된다. 검색된 모든 태그들의 리스트는 :tselect 명령으로 볼 수 있다.




:tselect




다음은 위 명령의 결과 이다.



:tag /^addr 명령 후 :tselect 의 결과






:tselect 명령을 실행하기 이전에 커서는 addrbytesof 함수의 정의 부분에 위치해 있었을 것이다. 위와 같은 상태에서 앞에 보이는 번호를 입력해 주면 해당하는 함수의 정의 부분으로 이동할 수 있다. vim 은 검색된 태그들 사이로 이동할 수도 있다. 현재 :tag /^addr 명령을 내린 직후 이거나 :tselect에서 1번을 선택하여 addrbytesof 함수의 정의 부분에 있다면, 이상태에서 :tnext 명령을 내려 2번째 검색 결과인 addrbytesptr 함수의 정의 부분으로 이동할 수 있다. 정규표현식으로 검색한 태그 내에서 이동하는 명령은 다음과 같다.


명령 설명


:tnext


검색 결과의 다음 태그로 이동


:tprevious


검색 결과의 이전 태그로 이동


:trewind


검색 결과의 처음 태그로 이동


:tlast


검색 결과의 마지막 태그로 이동


And