여러분의 CS 교육에서 누락된 학기 - 편집기(Vim) 1부

Hyuno Choi·2021년 8월 19일
1
post-thumbnail

이 포스팅은 MIT 공개 강의를 바탕으로 작성되었습니다. https://missing.csail.mit.edu/


2021년 8월 20일

VSCode 예찬론자의 Vim 사용기

드디어 missing semester 3주차 강의입니다. 이번 강의의 내용은 Vim 편집기의 기초적인 사용법에 대한 것입니다. 텍스트 편집기에 대한 취향은 개발자마다 확고하다고 알고 있습니다. 저 또한 대학에서 웹 프로그래밍 강의를 배울 때 처음으로 Visual Studio Code를 사용하고 나서는 VSCode의 매력에 빠져버렸습니다. 멋진 테마를 적용할 수도 있고 코드 자동 완성 기능이 무척 편했습니다. 무엇보다도 VSCode의 가장 큰 장점은 엄청난 익스텐션 생태계라고 생각합니다. 편집기에서 기본으로 제공하지 않는 기능들도 마치 게임에서 모드를 다운받듯이 익스텐션으로 커버할 수 있으니 말입니다. 심지어 VSCode는 무료입니다.

이러한 VSCode의 장점에 다른 편집기를 알아볼 생각도 하지 않았습니다. 인터넷상에서 Vim의 생산성에 대해 찬양하는 글을 많이 보았지만 저로서는 이렇게 훌륭한 현대의 편집기를 놔두고 굳이 과거의 커맨드라인 편집기를 사용할 필요는 없다고 생각했습니다. VSCode에서도 단축키를 통해 마우스를 적게 사용하는 법을 배울 수 있으니까요.

이번 강의를 듣고 제 생각이 조금은 바뀌었습니다. 최소한 지금 저의 VSCode에는 Vim 익스텐션이 깔려있습니다. Vim에서 제공하는 명령이 단축키와는 비교할 수 없을 정도의 생산성과 편리함을 제공한다는 것을 깨달았습니다. 물론 오늘 막 Vim을 제대로 사용하는 법을 익힌 참이고, 강의 노트에서 말하듯이 Vim의 기능을 제대로 익히는 방법은 '있을 법한' 기능이 떠오를 때마다 즉석에서 검색으로 배우고 익히는 것이라고 생각합니다. 지금 당장 자신에게 필요한 지식만큼 기억에 오래 남는 것도 없으니까요.

이번 강의 포스팅에서는 기본적인 Vim 사용법을 정리하겠습니다. Vim의 고급 기능은 에디터를 사용하며 그때그때 익히려고 합니다. 그렇다고 Vim을 주력 편집기로 사용하지는 않을 것입니다. 그것보단 VSCode에서 Vim 익스텐션을 사용하며 둘의 장점을 모두 가져올 생각입니다. 이제 본격적으로 강의 내용에 들어가보겠습니다.

Vim의 5가지 모드

프로그래머는 새로운 텍스트를 위에서 아래로 써내려가기만 하지 않습니다. 코드를 처음부터 끝까지 쭉 훑어보며 논리 구조를 파악하기도 하고, 파일 전체에서 특정 문자를 다른 문자로 모두 바꿀 때도 있고, 줄 단위로 코드를 삭제하고 복사할 때도 있습니다. 저 역시 프로그래밍 경험이 그리 오래되지 않았음에도 불구하고 이러한 작업들이 편집기 사용에서 차지하는 비중이 상당히 높습니다.

Vim은 이런 점을 잘 알고 있기 때문에 다중 모드를 지원합니다. 즉, 커서가 있는 곳에 텍스트를 적어넣기만 하는 것이 전부가 아닙니다. Vim에서 제공하는 모드는 다섯 가지입니다.

  • Normal: 기본 상태. 간단한 편집을 수행하거나 파일을 탐색합니다.
  • Insert: 텍스트를 커서 위치에 입력할 수 있습니다. 가장 일반적인 편집기의 기능입니다.
  • Replace: 텍스트를 변경할 수 있습니다. 풀배열 키보드에서 <INSERT> 키를 누르고 입력하는 것과 비슷한 기능입니다.
  • Visual: 텍스트 블럭을 선택하는 모드입니다. 마우스로 텍스트를 쭉 끌어서 선택하는 것과 비슷합니다.
  • Command-line: Vim 명령을 입력할 수 있는 모드입니다.

각각의 모드에 접근하는 방법은 다음과 같습니다. 어떤 모드에 있던지 일반 모드로 돌아가려면 <ESC>를 누릅니다. 일반 모드를 제외한 다른 모드들은 일반 모드 상태에서 진입합니다.

  • Normal: <ESC>
  • Insert: i
  • Replace: <Shift> + r
  • Command-line: :

Visual 모드의 경우 추가로 세 가지 옵션을 제공합니다.

  • 일반 비주얼 모드: v

  • 비주얼 라인 모드: <Shift> + v

  • 비주얼 블럭 모드: <Ctrl> + v

각 모드에 대한 자세한 설명은 밑에서 하겠습니다.

Vim 기본기

Vim을 사용하는 기본적인 방법이 missing semester 강의 노트에 나와있지만, 강의 노트 내용 대신 vimtutor 내용을 요약하겠습니다. 이번 주차 연습 문제에 vimtutor를 완료하라는 내용이 있기도 하고, 그쪽이 훨씬 설명이 풍부합니다. vimtutor는 Vim을 설치하면 따라오는 튜토리얼입니다. $ vimtutor 라고 쉘에 입력하면 실행할 수 있습니다.

Lesson 1

방향키 잊어버리기

Vim에서 커서를 움직이는 방법은 지금까지 컴퓨터를 사용해온 방법과 조금 다릅니다.

  • 상: k
  • 하: j
  • 좌: h
  • 우: l

이렇게 커서를 움직이는 것은 일반 모드와 비주얼 모드에서만 가능합니다. 만약 입력 모드에서 저 키들을 누른다면 단순히 현재 커서 위치에 hjkl 알파벳이 입력될 것입니다.

Vim의 전신인 Vi 편집기가 만들어진 시절에는 키보드에 방향키가 없었기 때문에 이런 방식으로 커서를 이동했다고 합니다. 지금은 물론 방향키로도 커서를 움직일 수 있습니다. 하지만 현재까지도 멀쩡한 방향키를 놔두고 hjkl을 방향키로 쓰는 이유는 어떻게든 손을 키보드 기본 파지법에서 벗어나지 않게 하기 위해서입니다. 타이핑을 하다가 오른손을 방향키로 옮기면 느껴지겠지만, 기본 위치에서 팔 전체가 이동하게 되고 타이핑의 흐름이 끊기게 됩니다. 하지만 hjkl는 기본 파지법을 유지하면서도 충분히 누를 수 있는 위치에 있기 때문에 방향키로 쓰는 습관을 들이면 타이핑의 흐름을 계속 유지할 수 있게 됩니다.

여담으로, 방향키 대신 hjkl키를 자유자재로 쓸 수 있게 되면 방향키가 없는 61키 이하의 미니 키보드도 사용할 수 있는 능력을 가질 수 있습니다 :D

Vim 시작하고 끝내기

윈도우 환경에서 Git bash를 통해 Vim을 사용할 때만 해도 편집기를 끄는 법을 몰라 터미널을 강제로 종료한 적이 많았습니다. Vim의 기본적인 종료와 시작 방법은 다음과 같습니다.

  • 시작: $ vim 혹은 $ vim [파일명]
  • 종료: (일반 모드에서) :q!

여기서 말하는 종료란 저장하지 않고 종료를 뜻합니다. 즉, Vim 편집기 상에서 어떤 짓을 했던지 간에 변경 내용이 저장되지 않습니다. Vim 시작 방법의 경우 $ vim 만 입력하면 빈 편집기가 실행됩니다. $ vim [파일명] 명령은 만약 그 파일이 존재한다면 파일을 열고, 존재하지 않는다면 해당 파일명으로 새 파일을 만듭니다.

초간단 삭제

입력 모드로 바꾸지 않고도 일반 모드에서 간단한 글자 삭제를 할 수 있습니다. 커서를 삭제를 원하는 글자 위로 옮기고 x 키를 누르면 글자가 삭제됩니다.

텍스트 삽입

i 키를 누르면 현재 커서의 위치에 텍스트를 삽입할 수 있습니다. 텍스트 편집기의 가장 기본적인 기능이라고 할 수 있습니다.

입력 모드로 원하는 텍스트를 입력한 다음에는 <ESC> 를 통해 일반 모드로 돌아가 커서를 옮길 수 있습니다. 입력 모드일 때는 하단에 INSERT라는 글자가 나타납니다.

줄 끝에 텍스트 추가

줄 맨 끝에 무언가를 추가해야 할 때가 있습니다. 그럴 때는 커서를 줄 끝까지 옮기고 입력 모드로 전환하기보다는 <Shift> + a 키로 두 동작을 한 번에 할 수 있습니다.

파일 저장 후 종료

:q!는 파일을 저장하지 않고 종료합니다. 편집기에서 수정한 내용을 저장하고 편집기를 종료하고 싶다면 :wq 를 사용합니다.

Lesson 2

단어 단위로 삭제하기

단어를 삭제하고자 할 경우 단어의 길이만큼 x 키를 누르지 않고도 삭제할 수 있는 방법이 있습니다. 일반 모드에서 삭제하려는 단어의 제일 앞에 커서를 놓고 dw를 입력하면 됩니다. 이 명령은 단어 뒤 공백까지 같이 제거합니다.

커서 위치에서 줄 끝까지 삭제하기

d$ 명령을 사용하면 현재 커서의 위치에서 줄 끝까지 삭제할 수 있습니다.

명령과 적용 대상

지금까지 dw라던지 d$ 같은 명령들을 사용해 원하는 부분을 삭제했습니다. 이 명령들은 독립된 명령이 아니라 명령과 적용 대상으로 이루어져 있습니다. 즉,

  • 명령: d (삭제해라)
  • 대상: w (단어) 혹은 $ (줄 끝까지)

으로 이루어져 있습니다. 간단하게 '대상'으로 쓸 수 있는 종류를 나열하면 다음과 같습니다.

  • w: 뒷 공백을 포함한 단어
  • e: 뒷 공백을 제외한 단어
  • $: 줄의 끝
  • 0: 줄의 시작

이러한 대상들을 명령 없이 사용하면 (예를 들어 w 만 누르면) '대상의 단위'만큼 이동합니다. 쉽게 말해 $를 누르면 줄 끝으로 커서가 이동하고 0 를 누르면 줄 앞으로 커서가 이동합니다. w 은 단어 뒤 공백을 포함하기 때문에 각 단어의 첫 글자에 커서가 위치하고, e는 단어 뒤 공백을 포함하지 않기 때문에 각 단어의 마지막 글자에 커서가 위치하게 됩니다(글로 쓰니 굉장히 헷갈리게 읽히는데 직접 해보면 바로 알 수 있습니다.).

여기서 알 수 있는 것은 Vim 명령이 다른 편집기의 단축키와는 비교할 수 없을 정도로 활용도가 높다는 것입니다. 고정되어 있는 단축키와는 달리 명령 + 반복 횟수 + 대상과 같은 조합을 활용하여 무수히 많은 상황에서 키보드만을 사용해 생산성을 높일 수 있습니다.

명령 반복 적용하기

이제 Vim 명령을 원하는 횟수만큼 반복하는 방법에 대해 알아보겠습니다. 간단합니다. w 를 눌러서 단어 단위로 커서를 움직였다면, 2w 명령은 두 단어를 건너뛰게 해줍니다. 같은 논리로 10w는 열 단어를 건너뛸 수 있습니다.

삭제 명령에 반복 적용하기

삭제 역시 반복 횟수를 지정할 수 있습니다. dw 가 한 단어를 삭제했다면 d2w는 두 단어를 삭제합니다.

줄 전체 삭제

아주 간단합니다. dd를 누르면(d 를 연속으로 두 번) 커서가 있는 줄 전체가 삭제됩니다. 여기서도 반복 횟수를 사용할 수 있습니다. 예를 들어 4dd 라고 입력하면 현재 커서가 있는 줄과 밑의 세 줄이 삭제됩니다.

undo & redo

undo와 redo 기능이 없는 편집기는 정신건강을 해칠 위험이 높습니다. 다행히 Vim은 두 기능 모두 지원합니다. undo는 u 키를, redo는 <Ctrl> + r 키를 누르면 됩니다.

lesson 3

붙여넣기

위에서 봤던 삭제 명령인 xd, dd 같은 것들은 사실 삭제라기보다는 '잘라내기'에 더 가깝습니다. 삭제 후에 p를 누르면 현재 커서 자리에 삭제했던 내용이 복사됩니다.

한 글자 바꾸기

단순히 한 글자를 잘못 썼을 경우 일반 모드에서 r 키를 눌러 수정할 수 있습니다. r 키를 누르고 다른 글자를 입력하면 현재 커서 위치의 글자가 입력한 글자로 바뀝니다.

한 단어 바꾸기

위에서 한 글자를 다른 글자로 바꿨다면 단어를 단위로 글자를 바꿀 수도 있습니다. ce 를 누르면 현재 커서를 기준으로 단어 전체를 지우고 입력 모드로 들어갑니다.

대상 변환

c 명령도 d 명령처럼 대상과 반복 횟수를 지정해줄 수 있습니다.

  • [횟수] c 대상 혹은
  • c [횟수] 대상 과 같이 사용합니다.

예를 들어 커서를 기준으로 3단어를 대체하는 명령은 c3w 라고 쓸 수 있습니다. 혹은, 현재 커서 위치부터 줄 끝까지 대체하는 명령을 c$ 로 쓸 수 있습니다.

Lesson 4

여러 줄 이동하기

지금까지 커서를 위아래로 이동할 때 jk를 썼습니다. 그러나 제일 마지막 줄이나 첫 줄로 이동하는 것과 같은 상황에서는 비효율적입니다.

  • 마지막 줄로 이동: <Shift> + g
  • 첫 줄로 이동: gg

또한 Vim에서는 특정 줄 번호로 이동하는 것이 가능합니다. <Ctrl> + g 를 누르면 현재 커서가 위치하고 있는 줄의 번호를 보여줍니다.

제일 아래쪽에 "lorem line" 으로 시작하는 줄이 줄 번호와 관련된 정보입니다. 현재 9줄 중에 4줄째에 위치하고 있으며, 전체 문서의 44%에 해당하는 부분이라고 합니다.

나중에 다른 줄에서 이 줄로 돌아가고 싶다면 4 + <Shift> + g 명령으로 돌아갈 수 있습니다.

검색

Vim 편집기 또한 다른 편집기와 마찬가지로 검색 기능을 제공합니다. / 키를 누르면 편집기 제일 밑에 / 표시가 뜹니다. 검색어(패턴)을 입력하고 엔터를 누르면 가장 처음 매치되는 결과를 보여줍니다. n을 누를 때마다 다음 결과로 이동하면서 결과를 순회합니다. 역방향으로 순회하려면 <Shift> + n 을 누릅니다.

<Shift> + n 을 눌러서 다시 위로 올라갈 때 밑을 자세히 보면 /the?the 로 바뀌어 있습니다. 위에서부터 탐색할 때는 /를, 아래에서부터 탐색할 때는 ? 를 사용합니다. 따라서 밑에서부터 검색하고 싶다면 ? 를 누르고 검색어를 입력합니다.

페이지가 길다면 검색어를 찾아 내려가다가 다시 검색 전의 커서 위치로 돌아가고 싶을 때가 있습니다. 그럴 때는 <Ctrl> + o를 누르면 됩니다. 그렇게 돌아가놓고 다시 검색어로 돌아가고 싶을 때는 <Ctrl> + i를 누릅니다.

괄호 짝 찾기

프로그램을 짤 때 괄호의 갯수가 많아지게 되면 나중에는 짝을 찾는 게 상당히 번거롭습니다. VSCode에서는 괄호 위에 커서를 올려놓으면 짝 커서를 자동으로 하이라이팅해줍니다. Vim에서는 괄호 위에 커서를 두고 % 를 누르면 짝 괄호로 커서를 이동합니다.

특정 문자 치환하기

특정 문자를 찾아서 그 문자를 다른 문자열로 바꿀 수 있습니다. 예를 들어 현재 커서가 있는 줄의 첫 번째 old를 new로 바꾸려면 :s/old/new 를 입력합니다. 그 줄의 모든 old를 대상으로 바꾸려면 :s/old/new/g 라고 입력합니다.

더 큰 범위를 대상으로 하는 치환은 다음과 같습니다.

  • :#,#s/old/new/g : 특정 줄번호와 줄번호 사이를 범위로 합니다.
  • :%s/old/new/g : 파일 전체를 범위로 합니다.
  • :%s/old/new/gc : 파일 전체를 범위로 하되, 하나하나씩 변경 여부를 물어봅니다.

Lesson 5

Vim에서 외부 명령 실행

터미널 창을 하나 더 열지 않고도 간단한 외부 명령을 Vim 편집기 내에서 실행할 수 있습니다. :! [명령]과 같이 사용합니다. 예를 들어, echo hello 를 Vim 안에서 실행하고 싶다면 :!echo hello를 입력하고 엔터를 누릅니다.

다른 이름으로 파일 저장

Vim으로 수정한 파일을 원래 파일에 저장하지 않고 다른 이름으로 저장하는 것이 가능합니다. :w [파일명] 명령을 사용합니다.

일부분만 다른 이름으로 저장

파일 전체를 다른 이름으로 저장하는 것 외에도 텍스트의 일부분만을 저장할 수 있습니다. v 키를 눌러 비주얼 모드로 들어가 선택 영역을 지정한 다음:w [파일명] 을 입력합니다. 아까와는 다르게 : 를 누르면 :'<,'> 라는 글자가 생깁니다.

file 이라는 이름으로 저장했습니다. $ cat file 명령으로 저장 내용을 확인해보면 선택 영역이 포함된 줄 전체가 저장되어 있습니다.

an unknown printer took a galley of type and scrambled

다른 파일 내용 읽어오기

이번에는 다른 파일에 적힌 내용을 현재 파일로 불러오는 방법에 대해 알아보겠습니다. :r [파일명] 명령어를 입력하면 현재 커서 위치 아래에 그 파일의 내용이 복사됩니다. 위에서 저장했던 file 의 내용을 빈 파일에 불러와보겠습니다.

:r 명령은 다른 파일의 내용 뿐만이 아니라 외부 명령의 결과도 가져올 수 있습니다. 예를 들어, :r !ls 명령은 현재 디렉토리의 파일들을 가져옵니다.

Lesson 6

새 줄 만들기

빽빽하게 차 있는 줄 사이에 커서를 기준으로 밑이나 위에 비어 있는 줄을 만들 수 있습니다.

  • o : 커서 아래에 새 줄 만들기
  • <Shift> + o : 커서 위에 새 줄 만들기

글자 추가하기

a 를 누르면 현재 커서 위치 바로 뒤에 글자를 추가할 수 있습니다. 특히 단어의 맨 마지막 글자에 커서가 위치하게 되는 e 키로 이동하면서 사용하면 효율적입니다.

여러 글자 교체하기

현재 커서 위치부터 시작해 적어 내려가는 내용으로 바꾸려면 <Shift> + r 키를 누릅니다. 교체를 끝내면 <ESC> 키로 다시 돌아옵니다.

복사-붙여넣기

비주얼 모드에서 선택 영역을 만든 다음에 y 키를 누르면 선택 영역이 복사됩니다. 그 후에 붙여넣고 싶은 위치에 커서를 옮기고 p 키를 누르면 커서 위치에 복사됩니다.

검색 옵션 설정

/? 를 사용해서 패턴을 검색하는 데 사용되는 옵션을 설정할 수 있습니다.

  • :set ic : 대소문자 무시
  • :set hls : 패턴과 일치하는 문자 강조

강조 기능을 켜면 다음과 같이 패턴과 일치하는 파일 내의 모든 문자가 강조됩니다.

각각의 옵션을 끄고자 하는 경우, 옵션 이름 앞에 no 를 붙이면 됩니다.

  • :set noic
  • :set nohls

내부 요소 변경

<>[] 처럼 무언가로 둘러싸여져 있는 요소를 바꿀 수 있는 기능도 있습니다. 예를 들어, <div> 태그를 <p> 태그로 바꾸려면 <div>의 아무데나 커서를 놓은 후, ci< 혹은 ci> 를 입력하면 자동으로 <> 안의 내용이 지워지고 입력 모드로 전환됩니다.

<> 를 남기지 않고 모두 지우려면 ci< 대신 ca< 를 입력합니다. 만약 "" 안의 내용을 모두 바꾸고 싶다면 ci" 라고 입력하면 됩니다.

이렇게 Vim의 기본적인 사용법을 모두 알아봤습니다. 물론 여기서 알아본 내용은 vimtutor 에서도 말하듯이 '기본'일 뿐이며, Vim을 더욱 효율적으로 사용하는 방법은 훨씬 많습니다. 그런 기능들을 익히기 위해 두꺼운 설명서를 사서 모두 외울 수도 있지만, 더 좋은 방법은 Vim을 사용하다가 더 효율적인 방법이 '있을 것 같을 때' 즉석에서 검색하고 공부하는 것이라고 생각합니다.

3주차 강의의 후반부 내용은 포스팅이 너무 길어져 2부에서 계속하겠습니다.

profile
프론트엔드 웹 개발자를 목표로 하고 있습니다.

0개의 댓글