[OS]/Embedded&Linux

C프로그래머를 위한 VIM 사용법

하늘을닮은호수M 2006. 12. 7. 11:34
반응형

출처 : JOINC(www.joinc.com)

1. 소개

이 문서는 Vim을 이용해서 C 프로그래밍을 하려는 개발자를 대상으로 작성되었다. Vim 초보자를 위한 문서이긴 하지만, 경험자에게도 많은 도움을 줄 수 있으리라 생각된다.

2. 이동

2.1. 문자단위 이동

C 소스파일을 열어서, W, e, b를 입력해 보기 바란다. vim은 각 토큰을 구분해서 빠르게 다음 토큰으로 이동 가능하도록 도와준다. 이 키들을 이용하면 좀더 빠르게 토큰사이의 이동이 가능하다.

	...	if((NULL == x) && y > z)	...
위의 if문 코드에서 w를 눌러보면 각 토큰의 처음으로 이동하는 걸 확인할 수 있을 것이다. 처음에는 ( 다음에는 == 토큰으로 이동한다.

e는 각 토큰의 마지막으로 이동한다는 걸 제외하고는 w와 동일하다.

b는 뒤로 이동한다는 걸 제외하고 w와 동일하다.

2.2. {,},[[,]] 키

{와 }는 문단단위의 이동을 위해서 사용한다. 문단은 비슷한 하나의 사물을 기술하는 여러 문장의 모음으로, 일반적으로 문서의 최소단위로 사용되며, 문서를 좀더 쉽게 읽을 수 있도록 도와준다.

/* first C-statment */....../* Next Set of C-statment */......
위의 예에서 {를 이용하면 문단의 처음이나 끝으로 한번에 이동할 수 있음을 확인할 수 있다.

C 코드 역시, 가독성을 높이기 위해서 아래의 예처럼 문단단위로 작성되는 경우가 많다. 논리적으로 비슷한 코드라인들을 하나의 문단으로 작성한다.(Vim은 한줄의 공백을 만나면 그다음 문단으로 생각한다)

void functin1(){	/* Declarations */	int x;	char y;	double z;	/* some code */	x = 1;	y = 'a';	z = 1.2;	/* some more code */	x++;	y++;	z++;}

[[]]는 {사이를 이동할 때 사용한다.

void foo(){ // ....}void bar(){ // ....}
[[는 이전의 {을 찾기위해서, ]]는 다음의 {를 찾기 위해서 사용한다. 이 키를 이용하면, 함수나 루프문의 처음을 빠르게 탐색 할수 있다. 위의 예제 코드에서 [[와 ]]를 이용해서 foo와 bar함수의 처음으로 이동하는걸 확인할 수 있을 것이다.

이외에도 [], ][와 같은 조합도 사용할 수 있다. 이들 키는 }를 탐색하는데 사용한다. []는 이전의 } ][는 다음 {로 바로 이동할 수 있다.

이들 키는 사용하기에 직관적이지 않다라는 단점을 가진다. 그래서 요즘 배포되는 vim은 좀더 직관적으로 사용가능하도록 다음과 같은 맵핑을 제공한다.

:map [[ ?{w99[{  :map ][ /}b99]}  :map ]] j0[[%/{  :map [] k$][%?}
[{와 ]}이 훨씬 직관적인 사용환경을 제공해줌을 알 수 있다.

2.3. % 키

if ((x==y) && ((z-=a) || (y>x)))
위의 코드는 여러개의 괄호가 중첩되어 있어서 괄호의 범위를 찾기가 쉽지 않다. %키를 이용하면 괄호의 시작과 끝위치를 쉽게 찾을 수 있다. %키는 이외에도 중첩된 #if, #ifdef, #else, #elif, #endif 문을 검사하기 위한 용도로도 사용할 수 있다.

3. C파일에서 임의의 위치로 이동하기

3.1. ctags

Tag는 코드에서 사용되는 논리적인 요소들의 집합을 정렬한 것으로, Tag를 이용하면 C코드를 쉽게 분석할 수 있다. C파일에 사용되는 함수들의 북마크 라고 이해할 수 있다. Tag는 특히, 함수의 원형을 보고자 할때, 유용하게 사용할 수 있다.

foo(){	...	bar();	...}bar(){	...}
foo함수를 분석하다보면 bar함수가 사용되고 있음을 알 수 있는데, bar함수가 어떤일을 하는지 명확히 알고 싶다면, 함수의 원형을 확인해 보는 수 밖에 없을 것이다. 만약 Tag를 사용하지 않는다면 vim의 찾기 기능이나 grep등을 이용해서 눈으로 확인해서 찾아야 할 것이다.

tag를 이용하면 CTRL-]CTRL-T 두개의 키로 함수원형으로의 이동을 간단하게 끝낼 수 있다.

tag기능은 물론 그냥 쓸 수는 없다. 모든 함수에 대해서 북마크 자료가 만들어져 있어야만 사용가능하기 때문이다. ctags명령을 사용하면 C코드들에 포함된 함수의 북마크를 생성할 수 있다.

# ctags *.c
만약 하부디렉토리에 있는 모든 C코드에 대한 북마크(테그)를 만들기를 원한다면 -R 옵션을 사용하면 된다.
# ctags -R *.c
ctags에 대한 자세한 설명은ctags 사용하기를 참고하기 바란다.

3.2. Mark

mark는 tag와 비슷한면이있다. 다른 점이라면 자신이 위치할 지점을 능동적으로 mark(표시)할 수 있고, 동일한 파일 내에서만 이동이 가능하다는 점이다.

자주 참고해야 하는 함수나 코드라인은 표시를 해두고 필요할 때 마다가 한번의 단축키로 찾아갈 수 있도록 한다면 매우 편리할 것이다. vim은 사용자가 표시한 라인을 기억하고 있다가 요청할 경우 바로 이동시켜주는 Mark 기능을 제공한다. 역시 일종의 북마크 기능이라고 볼 수 있을 것이다.

100 foo()101 {102	int x,y;103	x = 0;104	y = 1;105	x++;106	y++;107	if (x != y)108		x=y;109	y=x110 }
지금 당신은 foo함수에서 x++ 라인을 편집하고 있다. 그러다가 foo함수를 참조하는 다른 함수를 임시로 확인해야 하는 상황이 생겼다고 가정해 보자. 다른 함수의 확인이 끝났다면, 분명 당신은 원래 작업하던 위치인 x++로 돌아오길 원할 것이다. 당신의 기억력이 매우 좋다면 105라인을 기억해 두고 있다가 105G키를 입력해서 이동할 수 있긴 하겠지만 그리 좋은 방법이 아니다. 105라인에서 ma로 현재위치를 기억시키니 다음 기억된 위치로 가고자 할때 'a로 이동하는게 훨씬 편리하다. ma는 현재 위치를 a로 표시하겠다는 뜻이다. mb로 했다면 b로 표시하겠다라는 뜻이고 'b로 위치를 찾아갈 수 있다.

표시에 사용되는 이름은 단일 문자여야 한다. 그리고 대문자와 소문자를 구분하므로, 하나의 파일에서 약 50개 정도의 위치를 기억시킬 수 있다. 그러나 인간의 기억의 한계로 보통은 2-3개 정도의 위치만 기억시키고 사용하며, 이정도로도 충분히 유용하게 사용할 수 있다.

3.3. gd 키

아래와 같은 코드를 편집한다고 가정해보자.

struct X x;void foo(){	struct Y y;	struct Z z;	...	/* Lost of lines later */	x.bar();	y.bar();	z.bar();}
코딩을 하다보면 x,y,z이 도대체 어떻게 선언된건지를 까먹는 경우가 발생할 수 있다. 이럴경우 x,y의에서 gd키를 입력하면 선언된 위치로 바로 이동한다. gD는 전역에서 선언된 위치를 찾아서 이동한다. 일단 이동한 다음에는 원래 자리로 돌아오는게 좀 불편할 수 있는데, 3.2절와 함께 사용하면 불편함을 해소할 수 있다.

4. 자동완성

void A_Very_Long_Function_Name(){	...}short A_Very_Long_Variable_Name;void Another_Function(){	...	A_Very_Long_Function_Name();	...		}
위 코드를 보면 A_Very_Long_Function_Name 이라는 긴 이름의 함수가 사용되고 있다. 이렇게 이름이 길다보면, 이름을 기억하기가 쉽지 않아서, 나중에 함수를 쓸 때, 힘들게 기억해내야 하는 불편함이 발생한다. 기억을 해냈다고 하더라도 함수명을 쓰는 도중에 오타가 생겨날 수도 있다. 많은 IDE(12)들이 이러한 문제를 해결하기 위해서 자동완성 기능을 제공하는데, vim 역시 훌륭하게 자동완성 기능을 지원하고 있다.

A_Very 까지 입력하고 나서 CTRL-P를 입력해보기 바란다. 그러면 A_Very로 시작되는 함수/변수명 등을 검색할 수 있다. 위의 예제 코드는 2개의 A_Very로 시작하는 단어(함수와 변수)를 가지고 있는데, CTRL-P를 연속으로 누르면, A_Very로 시작되는 다음 단어를 검색하게 된다. 원하는 단어를 찾을 때까지 CTRL-P를 눌러주기만 하면 된다. 자동완성 기능은 vim의 입력모드에서 사용할 수 있다.

CTRL-P와 비슷하게 사용할 수 있는 CTRL-N키도 있다. 뒤로 검색한다는 걸 제외 하고는 CTRL-P와 동일하게 사용할 수 있다.

자동완성 기능은 기본적으로 현재 열린파일에서만 작동을 한다. 하지만 많은 경우 자동완성이 필요한 변수/클래스명 등은 외부파일에 따로 선언되는 경우가 많을 것이다. 이런경우 :set dictionary=file명령을 이용해서 자동완성을 위해 참조할 파일을 지정할 수 있다.

다음과 같이 C나 C++등에서 자주사용되는 키워드, 함수, 클래스이름 등을 정리해서 따로 사전파일로 만들어 두면, 좀더 편리한 개발환경을 만들 수 있을 것이다.

# cat .cdictbreakcasecontinuedefaultdefinedodoubleelseenumfloatgotoifndefifdefswitchtypedef

5. 포맷 자동 화

5.1. 라인 폭 조절

코딩을 하다보면 줄이 길어져서 화면의 폭을 넘어가는 경우가 생기는데, 이렇게 되면 코드의 가독성이 떨어지게 된다. 다음과 같은 명령으로 폭을 조정할 수 있다.

:set textwidth=80
이제 줄이 80열을 넘어가게 되면, 자동으로 다음 줄로 개행이 된다. vim의 시작시 위의 설정이 언제나 적용되게 하고 싶다면 .vimrc에 위의 명령을 적어 두면 된다.

5.2. 자동 들여쓰기

프로그램을 작성할 때, 코드의 가독성을 위해서 들여쓰기를 하게 된다. 아래와 같은 명령으로 자동으로 들여쓰기가 되도록 설정할 수 있다.

:set cindent

5.3. 주석완성

Vim은 자동주석완성 기능을 제공한다. 당신이 주석을 만들기를 원한다면 보통 세부분으로 이루어지게 될 것이다. 첫부분은 주석을 시작하는 부분이 될것이고, 중간부분은 주석 내용이 들어가고 마지막 부분은 주석을 닫는 부분이 될것이다.

/* * 주석입니다. */
위와 같은 주석 형식을 만들기를 원한다면, 아래의 명령데로 따라하면 된다.
:set comments=sl:/*,mb:*,elx:*/
약간은 암호문 같으니, 해석을 해보도록 하겠다. sl은 주석이 시작되는 시점을 vim에게 알려주기 위해서 사용한다. /* 문자열을 만나면 vim은 이후 주석을 자동으로 완성하게 된다. mb는 중간 주석문의 시작에 사용될 문자열을 정의 한다. 주석을 넣기 위해서 /* 로 주석을 시작한다음 개행문자를 입력하면, 다음 줄의 처음에는 mb에 정의된 문자열이 자동적으로 들어가게 된다. elx는 주석을 닫을 문자열을 지정하기 위해서 사용한다. 주석의 모든내용을 완성하고 주석을 닫기를 원한다면 / 를 입력하기만 하면 된다.

이번에는 주석의 형식을 약간 달리해보도록 하겠다.

/*** 2006년 2월 19일 ** 만 든 이 : yundream** 만든이유 : 심심해서*/
다음과 같이 약간 수정하는 정도로 자동완성될 주석의 형식을 변경할 수 있다.
				:set comments=sl:/*,mb:**,elx:*
/*을 입력하고 엔터키를 누르게 되면 vim은 주석완성기능을 수행하게 되고, 다음 줄의 처음에 자동적으로 **를 입력시켜주게 된다. 주석의 입력을 마치고 주석을 닫기를 원하다면 * 키를 입력하기만 하면된다. 그러면 마지막 *이 /으로 자동변환된다.

반응형

'[OS] > Embedded&Linux' 카테고리의 다른 글

pmap을 이용한 memory leak 검사  (0) 2006.12.19
GDB를 이용한 디버깅  (0) 2006.12.11
Windows Services for UNIX  (0) 2006.07.21
syslog daemon programming  (3) 2006.06.11
리눅스 시스템 모니터링과 문제 찾기  (0) 2006.05.12