2010년 11월 4일 Vim과 vi, 그리고 그 인터페이스
이전 글에서 이어진다.
Vim, 아니 그 전신이 되는 vi가 왜 현재의 형태 — 4dd, c$ 같은 류의 조합 가능한 명령 — 를 가지게 되었는지는 좀 역사를 설명해야 한다. vi는 생각보다 오래 된 편집기인데 (1976년) 원래 vi의 전신인 ex는 사용자 인터페이스라 할 만한 것이 없는, 그러니까 ed 급의 명령줄 편집기였다(라고 말하기 전에 ex가 ed에서 나왔다). 명령줄 편집기라고 하는 것은, 그러니까 한 화면에 전체 텍스트가 나오는 게 아니라 :3,5p 처럼 직접 어디부터 어디까지 출력하라고 해야 출력이 되는(…) 웃기지도 않은 것이었다. 근데 이게 불편하기 짝이 없는지라 visual mode(:vi, Vim에서의 normal mode)가 추가되었는데, 이 모드가 원래의 ex mode보다 훨씬 편하기 때문에 사람들이 ex만 켜면 :vi를 치고 시작하는 걸 보고 개발자가 새 명령 vi를 만든 것이 굳어 버린 것이다. 굴러 온 돌이 박힌 돌을 빼 낸 셈.
이 새로 추가된 visual mode는 당시의 느려 터진 터미널(빌 조이는 300 baud짜리 터미널을 썼다 한다)을 특별히 감안하여 만들어졌고, 때문에 터미널에서 정확히 갱신해야 할 문자만 출력해 주는 알고리즘1 따위가 존재했다. 조합 가능한 명령도 느린 터미널 때문에 생긴 것으로, 커서를 옮겨 다니면서 편집을 하려니 키보드를 쳤을 때 예상한 대로 동작할 지 확신할 수 없기 때문에 한 번에 커서를 옮겨 다니고 갱신하는 명령들을 갖게 된 것이다. 이를테면, 대부분의 vi 사용자는 다음 문장을 봤을 때:
The quick brown fox jumps over the lazy cog
커서가 저 줄 어딘가에 있고, “cog”를 “dog”로 바꾸려면 정확히 $Fcrd2라고 눌러야 한다는 걸 직감적으로 알고 있다. 보통의 위지윅 편집기에서도 End키 한 번 누르고 왼쪽 키 두 번 (또는 세 번) 누르고 Del 키 누르고 d를 찍으면 되긴 하지만, 저 뒤에 공백이 몇 개 있을 지 누가 아는가? 물론 왼쪽 키를 여러 번 누르는 대신 컨트롤 누르며 왼쪽 키 누르면 되긴 하지만 여전히 vi보다 신경써야 할 것이 많다. 느린 터미널이라는 현실적인 제약이 역설적으로 (적어도 이 예제에서는) 더 좋은 인터페이스 설계를 만든 것이다. 유닉스도 그렇지 않던가?
자, 여기까지는 vi 얘기였다. Vim은 어떤가? Vim 개발자를 탓하려는 건 아니긴 하지만, 난 Vim은 이런 큰 제약이 없었기 때문에 오히려 명령의 추가가 중구난방식으로 이루어졌다고 생각한다. 물론 중구난방이라고 쓸모가 없는 건 아니고, 있는 것만으로도 충분히 도움이 되는 기능도 많다 — visual mode(원래 vi의 그거 말고)라거나 그런 것들 말이다. 하지만 그래도 종종 지뢰를 밟는 경우가 있는데, 이를테면 내가 아는 한 blockwise visual mode(^V, 텍스트를 네모낳게 칸 단위로 선택)는 ex mode와 전혀 호환이 되지 않는다. 예를 들면 이 모드에서 :s/foo/bar/라고 쳐 넣으면 선택된 영역 안에서만 바뀔 걸 예상할 수 있지만 실제로는 linewise(V, 비슷하지만 줄 단위로 선택)와 똑같이 동작한다. 이는 사실 당연한 결과인데, ex mode 명령 :s는 애초에 블록 같은 걸 고려하고 만든게 아니기 때문이다. 또한 나는 visual mode에서 선택된 줄들에 동등한 명령을 내린다거나 하는 것이 왜 이렇게 귀찮은 건지 모르겠다. 앞 글에서 설명한 예제가 바로 이것인데, 사실 갯수가 명확하다면 매크로3로 해도 되지만, 갯수가 명확하지 않다면 앞에서 보인 것처럼 :norm 명령을 쓰는 게 거의 유일한 방법이다. 하지만 :norm 뒤에 명령을 썼을 때 그게 제대로 동작할 지 확신이 사실 안 서고 (매크로를 쓰는 이유 중 하나는 명령을 입력했을 때 그게 제대로 입력한 건지 확인하기 쉬워서니까), 앞에서 말했듯 블록에서는 전혀 원하는 대로 동작하지 않으니 난감한 노릇이다.
사실은 ex mode와 그 확장인 Vim 스크립트에도 불만이 많다. 본래 ed에서 물려 받았지만 이제는 별로 쓰일 것 같지 않은 :print 같은 명령이라거나 (음… 배치 모드라면 쓸 수도 있겠지만), 앞에서 봤듯 새로 추가된 모드와의 불협화음, 거지같이 복잡해진데다가 다른 주요 정규식 엔진과 문법이 상이한 엄청난 규모의 정규표현식(…), 그리고 왜 다른 좋은 임베디드 스크립트 엔진 놔두고 ex mode를 확장하는 건지 등등… 물론 Vim은 vi의 호환성을 유지하면서 발전해야 하는 중차대한 임무를 가지고 있기 때문에 일정 부분은 이해할 수 밖에 없지만 (그리고 Vim이 처음 나올 적에는 아직 쓸만한 스크립트 엔진이 많이 없었으니까), 그래도 불만이 있는 건 어쩔 수 없다.
프로그래밍 언어나 소프트웨어를 설계하는 것과 마찬가지로, 텍스트 편집기 같이 아주 빈번하게 쓰이는 사용자 인터페이스를 설계하는 데는 상당한 고민이 따라야 할 것이다. 내가 Vim에 아쉽게 느끼는 것은 vi만큼 섬세하고 주의깊게 설계된 사용자 인터페이스가 부족해서 그런 게 아닌가 싶다. 누군가가 새로운 — 어쩌면 vi 같은 모달(modal) 인터페이스를 가진 — 편집기를 만든다면, 이런 쪽에 대해서 좀 더 생각을 해 보길 권하는 바이다. 물론 그 누군가가 나는 아니겠지만;
-
실제로는 서로 연속되지 않은 문자가 갱신되었을 때 중간에 안 갱신된 문자들을 그대로 찍어 주는 게 (메타 문자가 없으므로) 전송량을 더 줄일 수 있어서 이런 부분도 고려를 한다. ↩
-
줄 맨 뒤로 가서(
$), 커서 뒤의 첫c를 찾고(Fc), 그 글자를d로 고친다(rd). ↩ -
말하자면 1000줄이 있다 치면
1Gi1. <Esc>qq0yf jP^Aq998@q식으로. 무슨 의미인지 아시겠는가? 혹시 이해하시겠다면 매크로에 대한 내 불만 — 왜 같은 명령을 n번 반복하는데@앞에는 n-1을 넣어야 하는가 — 도 이해하리라 믿는다. ↩
