메아리 저널

Vim에서 줄 번호 붙이기​

동아리 메일링 리스트에서 Vim으로 현재 버퍼의 모든 줄에 줄 번호를 붙일 수 있는지 얘기가 나와서 조금 생각해 봤는데, 의외로 어려운 문제였다. 일단 답만 알고 싶다면 Stackoverflow을 보는 게 좋겠다.

Vim만 쓰는 방법으로 내가 처음에 생각했던 것은 다음과 같았다. 여기서 ^R^M은 Ctrl-V를 누르고 각각 Ctrl-R/M을 눌러서 입력해야 한다.

:%norm i^R=line('.')^M. <엔터>

즉, 모든 줄(%)의 앞에서 삽입 모드로 들어간 뒤(norm i) 현재 줄의 번호(line('.'))를 커서 위치에 삽입(^R=...^M)하고, 그 뒤에 점과 공백을 입력하도록(.) 하는 것이다. 써 놓고 보면 사실 별게 아니긴 하지만 필요할 때 즉각 쳐 낼 수 있을 정도로 축약된 건 아닌데, 직접 찾아 보면 알 수 있듯 이게 최선인 듯 하다. 비슷한 형태의 명령으로 :%s/^/\=line('.').'. '/가 있지만 여전히 line('.')를 사용해야 하는 것이다.

만약 유닉스 유틸리티를 마음껏 쓸 수 있는 환경이라면 Vim에 의존하지 않고 다음과 같이 짜는 게 더 좋을 수 있다. 여기에 대한 설명은 생략.

!awk '{print NR". "$0}'
!perl -apne '$_="$.. $_"'

Stackoverflow에는 cat -n이나 nl을 쓰라는 조언도 있지만 직접 써 보면 포매팅을 맞추는 게 너무 어렵다. 아니, 그보다 cat -n은 cat -v만큼이나 좋지 않은 옵션이다. paste와 seq를 같이 쓰는 방법도 생각해 봤는데, paste가 가장 짧은 파일에서 멈추는 게 아니라 가장 긴 파일에서 멈춰 버려서 간단하게 나오질 않아서 (적어도 wc가 더 필요하다) 때려 쳤다.


여기까지는 이미 Vim(+ 유닉스 유틸리티)을 아는 사람을 위한 얘기였다. 정말로 하고 싶은 얘기는 반대이다: 왜 Vim은 이런 작업을 간단하게 할 수 없을까? 사실 아는 사람은 아는데, Vim은 의외로 없을 것 같은 기능이 기본으로 들어 가 있는 경우가 꽤 있다. 이를테면 8g8이나 g?? 같은 웃기지도 않은 기능들. 왜 이런 기능은 명령이 따로 있고 번호 붙이는 건 없는 걸까? 이 얘기는 다음 글에서 계속된다.


텀블러를 씁니다.