vi에서의 복사/붙이기

오랜만에 vi 글.

우분투를 쓸 때 vi는 정말 요긴한 도구이기는 하나 매우 긴 줄을 웹페이지에서 복사해서 붙이는 방법을 모르면 대략 난감한 상황이 오고, 아주 긴 내용을 붙여넣어야 할 때는 대략 정신이 멍해지기도 한다.

vi 안에서 복사하기 붙이기

vi안에서 글자를 복사하고 붙일 때는 문자열을 “레지스터”라는 곳에 복사하고, 이를 붙여넣는다. 그런데 이 레지스터는 우리가 흔히 생각하는 클립보드와 완전히 다른 공간이다. (vi 프로그램에서 사용하는 메모리 공간의 일부이다.)

레지스터에 문자열을 복사하는 동작을 vi에서는 “yank”라고 표현하고 명령 모드에서 y키를 사용한다. <횟수>y<대상>의 형태로 y w는 커서의 현재 위치에서 해당 단어의 끝까지를 복사한다. y y는 현재 라인을 복사한다. Y도 마찬가지로 현재 라인 전체를 복사한다.

이렇게 복사한 내용은 p 키를 눌러 붙여 넣을 수 있다. 만약 라인 단위로 복사하였다면 커서의 현재위치가 아닌 다음줄에 붙게 된다.

레지스터를 사용한 복사/붙여넣기

재밌는 점은 vi의 레지스터는 한 개가 아니다. 즉 여러 개의 레지스터에 각각 다른 내용을 복사해서 이를 붙일 수 있다. 레지스터를 지정하기 위해서는 겹따옴표를 사용하며, 레지스터 이름은 a~z까지 26개를 사용할 수 있다.

  • “aY : 현재라인을 레지스터 a에 복사한다.
  • “bp : 레지스터 b로부터 붙여넣는다.

클립보드에 복사하기/붙여넣기

하지만 이런 레지스터도 시스템의 클립보드와는 다른 공간이기 때문에 외부에서 복사해온 텍스트를 vi내에 붙여넣거나 vi에서 복사한 내용을 외부 프로그램에서 붙여넣기 위해서는 다른 방법을 써야 한다.

+(더하기 부호문자)는 시스템의 클립보드를 나타내는 좀 특별한 레지스터 기호이다. 따라서 다른 프로그램과 복사/붙여넣기를 호환하게 하려면 이를 사용하면 된다.

  • “+Y : 클립보드에 현재 라인을 복사
  • “+gP : 클립보드로부터 텍스트를 붙여넣고, 붙여넣은 위치 뒤로 커서 이동 (보통 붙여 넣으면 붙여 넣은 내용 뒤로 이동하니까)

그리고 이는 좀 더 간편히 사용하기 위해 따로 맵핑해두면 편리하다. .vimrc  파일에 다음 내용을 추가한다. 개인적으로 복사는 F3, 붙여넣기는 F4를 이용한다.

map <F3> "+Y
map <F4> "+gP
vmap <F3> "+y
vmap <F4> "+gP
imap <F4> <ESC>"+gPi

vmap은 비주얼모드 (블럭선택)시의 동작을 따로 정의하는 것이며 imap은 입력모드시의 동작이다. 당연히 입력모드에서는 복사를 할 수 없다.

이 방법은 윈도 및 우분투에서 사용이 가능하며, 윈도용 gVim 과 macVim(맥용 gVim)에서 사용이 가능하다. 단 OSX의 터미널에서 구동되는 vi에서는 페이스트보드(OSX의 클립보드)는 이 방법과 호환되지 않는다. (이 기능을 사용하기 위해서는 vi를 clipboard가 사용 가능하도록 새로 컴파일해서 쓰면 된다.)

추가(2012.09.24)

클립보드를 적용하는지 확인하고 싶다면 vim 명령 :echo has(‘clipboard’) 를 실행해서 그 결과가 1이면 (혹은 0이 아닌 다른 값) 사용가능하고 0이면 되지 않는다.

레지스터는 단지 복사/붙여넣기에만 사용하는 것이 아니라 파일의 특정 위치를 따로 기록할 때도 사용할 수 있다. 예를 들어 편집 중 m a 라고 하면 a라는 레지스터에 현재 위치를 저장해 둔다. 해당 위치로 이동하려면 a 를 누른다.

vi의 조금 편리한 기능들

사실은 조금 더 강력한 기능이랄까.

반복

  • . – (dot) 구두점은 마지막으로 실행한 명령을 다시 한 번 더 실행해준다. 명령의 반복은 다음과 같이 볼 수 있다.
  • {숫자} {명령} – 명령 앞에 숫자를 붙이면 그 숫자만큼 반복하게 된다. 이동할 때 3 w라고 하면 세 단어를 이동하는 데 이것이 사실은 거의 모든 명령에도 적용될 수 있다.
2dd     # 현재 줄을 포함하여 2줄을 삭제한다.
3p      # 잘라낸 2줄을 3번 붙인다.
100iDescription <ESC>  # 'Description '을 100번 삽입한다.
.       # 위의 것을 1번 더 즉 100번 더 쓴다.
3p      # 100번 쓰는 것을 3번 하니 300번을 더 쓴다.

특정 지점으로 이동

w로 다음 단어의 첫 글자로 이동하거나, e로 단어의 끝으로 이동하는 것 외에 몇 가지 추가적인 이동 명령. 역시 이동 명령은 ‘선택’하는 액션과 동일하게 동작하므로 살펴보면 도움이 된다.

  • f a – 다음에 나타나는 ‘a’로 이동. 3 f a는 다음에 나타내는 a 중 3번째로 이동. 대문자는 역 방향.
  • t a – 다음에 나타나는 ‘a’의 바로 앞으로 이동. 대문자는 역방향.
  • % – 괄호 (대/중/소)에서 입력하면 그에 상응하는 괄호로 이동함. 코드에서 괄호를 안 닫거나 하는 부분을 찾기가 아주 편리하다.
  • ] ) – 다음번 닫는 괄호로 이동한다. 여는 괄호로 이동은 ](. 다른 괄호 종류에 대해서도 동일하게 적용됨
  • ( , ) – 이전/다음 문장
  • {, } – 이전/다음 문단

Visual Mode

비주얼 모드는 텍스트의 일부 구간을 선택하는데 시각적으로 선택된 텍스트를 반전시켜 어떤 텍스트가 선택되는지를 눈으로 보여준다. 비주얼 모드와 비슷하게 비주얼 블록 모드가 있는데 이는 화면상에 사각형 영역으로 (행전체가 선택되지 않게) 선택할 수 있다. (일부 좋은 기능들이 많은 텍스트 편집기들이 이런 기능을 지원하고는 있음)

  • v i – 따옴표로 둘러싼 영역을 모두 선택
  • v a – 따옴표로 둘러싼 영역을 따옴표를 포함하여 선택
  • v – 비주얼 모드 시작. 비주얼 모드를 시작하면 현재 위치로부터 커서를 옮기는 만큼 색상이 반전되며 선택된다. 선택된 내용에 대해 d 나 y 로 오려두기/복사하기를 할 수 있다.
  •  ^v – (Ctrl + v)비주얼 블록 모드. 비주얼 블록 모드는 행 단위가아닌 열 단위로 선택하게 한다.
  • I, A – i, a 의 대문자. 비주얼 블록 모드로 선택한 여러 행에 걸친 위치에 같은 내용을 삽입한다. 예를 들어 1행부터 40행까지의 내용을 “// “으로 주석처리하고자 한다면 다음과 같이한다. (아래 [^v]는 control+v를 말하며 공백은 스페이스바를 입력했음을 의미한다.)
g g 0 ^v 3 9 j I// ESC
  • gg – 1번행으로 간다.
  • 0 – 맨 왼쪽으로 간다
  • [^v] – 비주얼 블록 모드 시작
  • 39j – 39행 아래로 이동하여 40행까지 첫번째 열을 모두 선택
  • I – multiple insert mode 시작
  • //  – “// ” 입력
  • [ESC] – 삽입모드 종료. 40행까지 모두 주석처리가 된다.
  • <,>  – 비주얼 모드에서 선택된 라인들에 대해 좌/우 방향으로 들여쓰기, 내어쓰기를 적용
  • = – 비주얼 모드에서 선택된 라인들에 대해 자동 들여쓰기 (정말 쿨함)

자동완성

insert mode에서 입력중에 ^p를 누르면 이전에 입력한 적 있는 단어 중에서 비슷한 단어를 자동완성해주는 기능이 있다.

창 분할

  • :split – 창을 상/하 분할한다. (분할된 공간에는 새 파일을 만들 수 있다.)
  • :vsplit – 창을 좌/우 분할한다.
  • ^w ^w – 분할된 창 사이를 이동할 수 있다.
  • ^w _ – 현재 창을 최대화 (분할된 공간을 최대화함)
  • ^w | – 현재 창을 최대화 (세로 분할인 경우)
  • :tabnew – 새로운 탭을 만든다.
  • g t – 다른 탭으로 이동한다.

vi 기본 사용법

vi은 대부분의 유닉스나 리눅스 시스템에 설치되어 있다고 믿어도 좋을만큼 널리 퍼져있는 텍스트 편집기이고, 매우 오랜 역사를 가지고 있는 텍스트 편집기이다. 일견, 상식적으로 이해가 힘들 것 같은 조작법 때문에 재미삼아 열어봤다가는 메뉴 등등 익숙한 문서 편집 프로그램에서 볼 수 있는 UI도 없기 때문에 낭패를 보기 십상이지만, 터미널에서 텍스트 파일을 작성하거나 편집할 때 유용하게 사용할 수 있다. 익혀두면 좋을 뿐더러 엄청 편리한 기능들을 제공하기 때문에 오늘날에도 많은 개발자들의 사랑을 받고 있는 편집기..라고 한다.

텍스트로 구성된 설정파일이나 하다 못해 hosts 파일 수정에는 더 없이 깔끔하니 좋은 프로그램이다보니 한 번쯤은 사용법을 익혀서 정리해 둘 봄 즉도 해서 정리한다.

기본 컨셉

vi는 일반적인 메모장과는 완전히 다른 인터페이스를 가지고 있다. 모든 것이 ‘명령’으로 이루어지고 이들 ‘명령’은 키를 누르는 것으로 입력된다. 또한 이 ‘명령’들은 간소하나마 자신만의 문법을 가지고 있다. 텍스트를 입력하는 것은 명령모드에서 입력모드 (insert mode)로 전환한 후에야 가능하며, 다시 명령 모드로 돌아가기 위해서는 ESC 키를 눌러 준다. vi의 화면 맨 아래에는 현재 상태를 표시해주는 줄이 있다. 이 줄에서 insert 가 표시되는지 안되는지를 눈여겨 보면 좋다.

vi는 터미널에서 vi 명령으로 실행할 수 있고, 다음처럼 파일 이름을 덧붙여 준다. 파일이 존재하는 경우에는 그 파일을 열고, 새로운 파일 이름인 경우에는 파일을 생성한다.

vi ~/mytext.txt

커서 이동

vi에서는 커서 이동도 하나의 명령이다. 이 개념을 이해 못하면 완전 낭패를 볼 수 있다. 물론 ㅍ플랫폼이나 버전에 따라서 약간 다를 수는 있는데 기본적으로 화살표 키가 아닌 h,j,k,l 키로 커서 이동을 한다. 한 번에 한 칸씩 이동하는 게 좀 답답하니까 몇 가지 추가적인 기능을 더해 제공해고 있다. 최소한 이 이동에 관한 내용은 외워줘야 한다.

  • j – 한 칸 아래로 이동
  • k – 한 칸 위로 이동
  • h – 한 칸 왼쪽으로 이동
  • l – 한 칸 오른쪽으로 이동
  • w – 한 단어만큼 앞쪽으로 점프 (여기서 앞쪽이란 문서를 써나가는 방향이다.)
  • b – 한 단어만큼 뒤쪽으로 점프
  • 0 – (숫자 0) 현재 줄의 시작지점으로 점프
  • $ – 현재 줄의 끝 지점으로 점프
  • ^ – 현재 줄에서 공백이 아닌 첫 글자로 점프
  • g g – 파일의 맨 첫줄로 점프
  • G – (shift + g) 파일의 맨 끝으로 점프
  • (숫자)G – 해당 번호의 행으로 점프
  • ^f – (ctrl+F)다음 페이지로 이동. 특히 도움말을 볼 때 유용하다.
  • ^b – 이전 페이지로 이동.

각각의 키들은 단순히 방향키를 치환한 것이 아니라 하나의 명령이다. vi에서 재밌는 것은 숫자와 함께 사용하여 명령을 실행할 수 있다. 예를 들어 h 는 한 칸 왼쪽으로 이동하는데, 8h 라고 입력하면 8칸 왼쪽으로 이동할 수 있다. 같은 방법으로 9j 는 9줄 아래로 이동한다.

입력과 삭제

vi에서 텍스트를 입력하는 것은 사실 ‘추가’이다. 추가는 추가 모드로 진입한 후 타이핑을 하면 이 때부터 타이핑되는 글자들은 모두 파일의 내용으로 기록된다.

  • i – 현재 커서 위치에서부터 텍스트 삽입을 시작한다.
  • <ESC> –  esc키를 누르면 삽입 모드를 빠져나가 명령모드로 진입한다.
  • a – append. 현재 커서 위치 다음 글자부터 텍스트를 붙여 준다.
  • o – 현재 커서의 바로 다음에 새 줄을 추가하고 다음줄에서 바로 삽입모드로 전환된다.
  • O – (shift + o) 커서의 바로 위에 새 줄을 추가해준다.

삭제

삭제는 커서를 기준으로 글자를 지우거나, 단어를 지우거나 하는 등의 동작이다. 재밌는 것은 입력모드에서는 백 스페이스 키를 눌러서 입력하던 글자를 얼마든지 지울 수 있는데, 입력모드가 끝나고 나면 삭제 명령으로 지워야 한다. (백스페이스키는 보통 왼쪽으로 이동하는 것과 동일하게 작동하는 경우가 많다.)

  • x – 커서가 위치한 곳의 글자를 지운다.
  • d h – 커서가 위치한 곳에서 부터 한칸 앞쪽으로 지운다. delete + h 인 셈인데, 이를 활용하여 d3h 하면 현재 커서 위치로 부터 3칸 앞의 글자들을 지울 수 있다. 즉 d 와 이동 명령을 결합하여 커서가 지나가는 자리만큼을 지운다.
  • d j – 현재줄을 포함하여 다음 줄까지 2줄을 지우게 된다.
  • d d – 가장 많이 쓰는 것은 아마 현재 줄을 지우는 경우일 것이다. dd는 현재 줄을 지운다.

삭제는 사실 “오려두기”이다. 이는 뒤에서 다시 설명하겠다.

고치기

오타를 수정하거나 하려면 덮어쓰기를 시전하면 된다. 다음과 같은 명령들이 있다.

  • r – 현재 커서 위치에서 한 글자만 바꾼다. 커서가 위치한 곳의 글자가 a 인경우 rb 라고 누르면 a가 b로 바뀐다. 한글자만 딱 입력받아 바꿔준다.
  • R – 수정모드가 되어 ESC를 누를 때까지 현재 줄의 내용을 수정해 준다. 재밌는 것은 수정 모드에서는 백스페이스키를 누르면 입력한 글자가 지워지는 것이 아니라 기존에 있던 글자로 되돌아간다는 점이다.
  • c –  change로 이동 명령과 결합하여 한 글자를 지우고 입력모드가 된다. 즉 커서위의 글자가 입력한 글자들로 바뀌게 된다. cl 이라고 입력하면 커서위의 글자가 지워진다.
  • c w – c+w로 커서 위치부터 그 단어의 끝까지가 새로 입력한 글자들로 대체된다. 즉 change + w로 실행되었다고 보면 된다. 비슷하게 c $ 하면 커서 위치부터 그 줄 끝까지를 지우고 새로 쓰게 되는 것이다.
  • C – c$와 같다.
  • s – cl 과 같다. 한 글자만 지우고 입력한다.
  • S – 줄 전체를 새로 쓴다. s는 아마 subtitute의 머리글자인 것 같다.

복사와 붙이기

복사 명령은 y 이다. y y는 현재 라인을 복사하고, 2 y y는 현재 라인을 포함한 두 줄을 복사한다.

  • y – 복사 시작. y 다음에 이동 명령을 조합하여 복사할 범위를 지정한다.
  • y w – 단어 끝까지 복사
  • y $ – 현재 줄의 끝까지 복사
  • p – 붙여 넣기. 만약 줄을 복사하였다면 현재 커서위치가 아닌 바로 아래쪽에 줄이 붙는다.

또한 x, d 등을 통해 삭제한 글자들은 모두 ‘오려두기’로 지우고 메모리에 저장되어 있으므로 p를 사용하여 붙여넣을 수 있다.

되돌리기

  • u – 한 번의 변경을 되돌릴 수 있다.
  • U – 한 줄에 대해 변경사항을 모두 되돌린다.
  • ^r – (ctrl+R) 되돌린 내용을 다시 적용한다.

되돌리기도 물론 지원하고 있다. 기본적으로 약 50번 정도의 undo를 지원하는 듯. 이쯤에서 메모장이 더 이상 아쉽지 않기 시작한다.

저장과 종료

편집이 아닌 파일에 접근하는 등의 명령은 : 로 시작한다. : 를 입력하면 화면 맨 아래에 : 가 입력되고 명령을 수행할 준비를 한다. 아래는 저장 종료 및 기타 유용한 명령들이다.

  • :cd – 현재 디렉토리를 보여준다.
  • :cd _PATHNAME_ – 다른 디렉토리로 변경한다.
  • :!{shell command} – 쉘 명령를 vi 안에서 실행한다. :!ls 하면 현재 디렉토리의 파일 목록을 확인할 수 있다. 명령 실행이 완료되면 엔터를 눌러 복귀한다.
  • ^g : 현재 행 번호를 보여준다.
  • :w – 현재 내용을 디스크에 기록한다.
  • :w __FILEPATH__ – 현재 내용을 다른 이름으로 저장할 수 있다.
  • :q – 종료한다. 만약 편집된 내용이 있다면 종료가 안된다.
  • :wq – 저장 후 종료한다.
  • :q! – 무조건 종료한다. 편집한 내용은 기록되지 않는다.
  • Z Z – 내용을 저장하고 종료한다.

찾기와 바꾸기

  • / – 패턴을 검색할 수 있다. 패턴은 당연히! 정규식을 지원한다. 점점 메모장과는 다른 세상이다.
  • n – 다음 검색 결과로 이동한다. 파일 끝까지 이동했다면 다시 맨 처음 검색 결과로 돌아간다.
  • N – 이전 검색 결과로 이동한다.
  • : %s/old/new – old를 찾아 new로 바꿔준다.
  • : %s/old/new/g – 전체를 검색하여 한 번에 모두 바꾼다.
  • : %s/old/new/gc – 위와 같은데 바꿀 때 마다 물어보게 한다. (c는 confirmation)

도움말 사용하기

vi 나름 잘 문서화된 도움말도 제공하고 있다. 도움말을 실행하는 명령은 :help 이다. 이 명령에는 다른 명령을 붙여 해당 명령의 도움말을 바로 확인할 수 있는 기능도 있다.

  • :help – 도움말을 시작한다. 도움말은 분리된 창의 형태로 보인다.
  • :help :cd – :cd 명령에 대한 도움말을 볼 수 있다.
  • ^] – 도움말내의 각 인덱스는 |01.1 인덱스제목| 과 같은 식으로 표시되는데, 커서를 이곳으로 옮기고 ^] 를 누르면 해당 항목으로 바로 이동한다.
  • ^t – 위에서 이동한 방식으로 문서를 탐색하다가 다시 되돌아가는 기능이다.
  • ^w ^w : 분리된 창 사이를 이동할 수 있다. (컨트롤 키를 누른 상태로 w키를 두 번 누른다)

간략히 살펴본 바와 같이 vi는 언뜻 처음에 볼 때는 사용하는 사람이 이해가 가지 않는 동작 방식 때문에 적잖이 당황스러울 수 있는데, 역시나 익숙해지려 조금만 노력하면 상당히 강력한 도구가 될 수 있을 것 같다.

vim을 별도로 설치한 경우에는 tutor 모드가 있는데, 이를 실행해서 기본적인 이동이나 편집 방법만 익혀두면 매뉴얼을 일일이 찾아보면서 익히는 것보다 훨씬 더 빠르고 효과적으로 배울 수 있다. (vi를 좀 사용할 일이 있다면 이를 적극 권장함)

끝으로 vi는 도저히 못쓰겠다. 그런데 터미널에서 파일 편집은 할일이 있다… 는 사람들은 nano 를 대신 쓰면 된다. nano는 그나마 비교적 메모장에 가깝게 생긴 프로그램이다. (ctrl+N 등과 같은 방식의 단축키도 지원하고 있고…)