vim의 레지스터

vim의 저장공간인 레지스터에 대해 살펴보자

vim의 레지스터
Photo by Nuno Silva / Unsplash

복사와 붙여넣기에 대해서 크게 고민하면서 사용해 본 경험들은 거의 없을 겁니다. 우리는 이 기능들을 마치 물과 공기처럼 당연한 것으로 생각하고 사용하고 있습니다. 특히 반복적인 편집에 복사와 붙여넣기 기능은 꼭 필요한 기능이기도 하죠.

대부분의 프로그램들은 복사/붙여넣기 기능을 '클립보드'를 통해서 구현합니다. 클립보드를 사용하면 복사한 내용을 같은 프로그램 뿐만 아니라 다른 프로그램에서도 붙여넣어서 사용할 수 있죠. 사실 클립보드는 프로그램 사이에서 데이터를 주고 받는 매커니즘을 포함하기 때문에, OS에서 제공하는 기반 기술을 사용합니다. 그런데, 동시에 여러 프로그램이 실행되고 사용자가 이 프로그램 사이를 오가면서 사용하는 환경은 비교적 최근의 일입니다.

이 말은 vi/vim의 초창기에는 OS에서 클립보드와 같은 기능을 제공하지 않았다는 것을 의미합니다. 그러면 클립보드가 없을 때, vim에서는 어떻게 복사와 붙여넣기가 가능했을까요?

레지스터

텍스트를 조작할 수 있는 많은 고전(?) 프로그램들은 보통 자신만의 저장 공간을 따로 정의해놓고 쓰는 경우가 많은데, vim 역시 레지스터라는 공간들을 정의해놓고 있습니다. vim의 레지스터는 여러 개가 있고, 각각 이름으로 구분합니다. a ... z 까지의 알파벳 이름을 가진 레지스터는 사용자가 사용하는 공간으로 할당되어 있고, 그 외에 숫자 레지스터, 검색 레지스터 등등 여러 레지스터가 있습니다. 우선은 사용자에게 할당되어 있는 레지스터 사용법부터 한 번 알아보겠습니다.

복사나 붙여넣기 동작에서 레지스터를 사용할 때에는 복사, 붙여넣기 명령 앞에 사용할 레지스터를 지정합니다. 레지스터를 지정하는 키는 "입니다. y나 p 명령 바로 앞에 "x 와 같이 레지스터를 지정해줄 수 있습니다.

(특정 영역을 선택한 selection 모드에서)
"ay  <- 레지스터 a에 선택한 텍스트를 복사 

(붙여넣을 곳으로 이동한 후 normal 모드에서)
3"aP <- 레지스터 a에 복사된 텍스트를 3회 붙여넣기

vim에서 레지스터는 사실 알게 모르게 상당히 여러 용도로 사용되고 있습니다. 레지스터의 종류는 대략 다음과 같은 것들이 있습니다.

  • A...Z 레지스터
  • 숫자 레지스터
  • 이름이 없는 레지스터
  • 명령, 검색 레지스터
  • 그 외 레지스터
💡
보다 자세한 레지스터들에 대한 설명은 vim 도움말을 참고하기 바랍니다. :h {register} 라고 입력하면 관련 문서를 볼 수 있습니다.
Vim: change.txt
Vim help pages, always up-to-date

알파벳 레지스터

각각의 알파벳 문자를 이름으로 하는 26개의 레지스터가 있고, 이들은 모두 사용자가 자유롭게 사용할 수 있습니다. 이들은 'named registeres'로 분류됩니다. 참고로 매크로를 녹화할 때, q를 누른 다음에 이를 저장할 키를 하나 더 누르게 되는데, 이 때에도 해당 키 문자가 가리키는 레지스터에 입력한 키 스트로크를 순서대로 기록하게 됩니다.

알파벳 레지스터는 26개이지만, 레지스터에 쓸 때에는 레지스터 이름을 소문자나 대문자로 쓸 수 있습니다. 소문자로 쓸 때에는 기존에 레지스터에 들어있는 값을 지우고 새로운 값으로 대체하며, 대문자로 쓸 때에는 기존에 있는 값에 새로운 값을 추가하는 식으로 작동합니다.

숫자 레지스터

"0은 가장 최근에 복사(yank)한 내용이 자동으로 기록됩니다. (단, 복사 명령에서 명시적으로 특정한 레지스터를 지정했다면 같이 기록하지는 않습니다.)

"1 ~ "9는 각각 최근에 삭제한 텍스트가 순서대로 들어있습니다.

무명 레지스터

""은 이름이 없는 레지스터로, 가장 최근에 복사하거나 삭제한 내용이 기록됩니다. 그 자체는 따로 저장공간을 가지고 있다기 보다는 마지막에 액세스한 레지스터를 가리킨다고 보면 될 것 같습니다.

기타 레지스터

  • "/ : 가장 최근에 사용한 검색어
  • "- : 삭제 레지스터. 가장 최근 삭제된 한 줄 이하 크기의 레지스터
  • "+, "* : 클립보드 레지스터. vim이 클립보드를 지원하도록 컴파일 되었을 때에만 사용할 수 있습니다. +clipboard 기능이 없는 경우에는 무명 레지스터와 똑같이 작동합니다.

다음 세 레지스터는 유용한 정보를 담고 있는 대신, 외부에서 변경할 수 없다.

  • ": : 가장 최근에 실행된 명령줄 명령
  • ". : 가장 최근에 추가된 텍스트
  • "% : 현재 파일 이름.

레지스터와 vimscript

각각의 레지스터에 들어있는 값은 vimscript에서도 읽고 쓸 수 있습니다. vim 스크립트에서 각각의 레지스터는 @x와 같이 @문자를 앞에 붙여서 참조합니다. 주로 여러 함수 사이에서 값을 직접 전달할 수 없을 때, 미리 약속한 레지스터에 값을 써 두었다가 사용하는 방식으로 사용합니다.

수식 레지스터

수식 레지스터 혹은 표현식 레지스터(expression register)는 그 자체로 레지스터는 아니며, vimscript의 표현식의 결과를 레지스터의 값으로 사용하려할 때 사용합니다. 예를 들어 입력모드에서 ctrl + R을 누른 후 특정한 레지스터의 이름을 입력하면 해당 레지스터의 내용을 자동으로 입력해줍니다. 이 때 ctrl+R =을 순서대로 누르면 하단 명령줄이 "="로 시작하는 수식 입력줄이 되는데, 이 때 특정한 수식이나 vimscript 함수를 입력하여 그 결과를 삽입할 수 있습니다.

" 1. 입력모드에서 아래 줄을 입력
filename: 
"        ^ 2, 이 위치에서 ctrl+R
=expand("%:p")  " 3. 아래쪽에서 수식입력 후 엔터

->
filename:D:\myfiles\current_file.txt
         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 4. 절대경로로 확장된 파일명 삽입

수식 레지스터 사용 예시