콘텐츠로 건너뛰기
Home » Vim에서 점프하기

Vim에서 점프하기

Vim에서 우리는 ‘마크’라는 것을 사용하여 특정한 파일의 특정한 위치에 표식을 남겨두고 단축키를 사용하여 해당 위치로 언제든 돌아갈 수 있습니다. 특정 위치에 a 라는 마크를 남기고 다시 다른 파일을 편집하던 중에 이전에 마킹해놓은 위치로 돌아가는 동작을 Vim에서는 “점프”라고 합니다. Vim에서 이러한 점프는 현재 창에서 새로운 버퍼를 연다거나, 이전 편집 위치로 이동하거나 하는 등의, 스크롤을 통한 이동을 제외한 대부분의 이동이 해당됩니다.

Vim에서 편집을 하던 중에 점프가 발생하면, Vim은 점프를 하기 전에 현재 ‘위치’를 “점프 리스트”라는 큐에 기록합니다. 그래서 점프를 통해 다른 곳으로 이동하더라도 마치 브라우저의 히스토리처럼 이전 위치들의 목록을 가지고 있게 되고, 당연히 이전 점프 시점으로 되돌아갈 수도 있습니다.

노멀모드 명령인 <C-o>,<C-i> 가 점프리스트에서 앞/뒤로 움직이는 이동에 해당합니다. 특히 도움말에서 관련 항목으로 바로 이동한 후에 이전 위치로 돌아갈 때에도 사용할 수 있습니다.

이처럼 Vim에서는 특정한 시점의 이전 커서 위치로 바로 돌아갈 수 있는 기능이 몇 가지 있습니다.

  1. 마크 : 수동으로 표시해놓은 위치
  2. 점프 리스트 : 다른 곳으로 점프할 때마다 기록되는 이력
  3. 변경 리스트 : 버퍼의 내용을 변경할 때마다 기록되는 이력

오늘은 이러한 점프를 사용하여 파일 내에서 혹은 다른 여러 파일 사이에서 특정한 위치로 빠르게 이동하는 방법을 알아보겠습니다.

마크

마크(mark)는 말 그대로 특정한 위치에 표식을 남기는 것입니다. 수동으로 사용할 수 있는 마크에는 소문자 및 대문자와 홑따옴표가 있습니다.

  • m{a-zA-Z} : 현재 커서의 위치를 지정한 이름의 마크로 기록합니다. ma 라고 누르면 현재 위치를 ‘a’ 라는 마크에 기록합니다.
  • `{a-zA-Z} : 기록해 두었던 마크의 위치로 되돌아 갑니다.
  • '{a-zA-Z} : 백팃과 마찬가지로 기록해두었던 마크의 위치로 되돌아 갑니다만, 커서의 위치는 해당 라인의 맨 앞 (공백이 아닌 맨 앞 글자)으로 가게 됩니다.
  • :marks :현재 기록되어 있는 전체 마크를 표시해줍니다. 마크가 잘 기억나지 않는다면, 이를 보고 이동할 위치를 알아볼 수 있습니다. 현재 파일 내의 마크는 해당 부분의 텍스트가 표시되고, 다른 파일인 경우에는 파일 경로가 표시됩니다.

현재 위치에서 특정한 마크로 이동하는 것도 “점프”에 해당합니다. 따라서 마크로 이동할 때에는 점프리스트에 현재 위치를 또 추가하게 됩니다. 마크로 이동하는 명령 앞에 g를 붙이면 점프 리스트를 변경하지 않고 이동합니다. 일반적으로는 쓸 일이 없고, vim script 에서 특정한 위치를 오가게 만들 때 사용할 것 같습니다. (개인적으로는 써 본 적 없음)

그 외 vim 도움말에서 특별히 언급하는 마크에는 이런 것들이 있습니다.

  • ' : (홑따옴표) 직전 위치
  • " : (겹따옴표) 마지막 편집 위치
  • [, ] : 각각 최근 편집의 시작위치, 끝 위치를 말한다.
  • <, > : 각각 최근 visual 모드로 선택한 영역의 시작, 끝 위치를 말한다.

점프 리스트

점프 리스트는 스크롤이나, 상하좌우 이동 혹은 단어간 이동이 아닌 커서 이동이 발생할 때마다 점프 하기 전 위치를 기록합니다. 우리 눈에는 점프처럼 보이지만 점프가 아닌 이동에는 이런 것들이 있습니다.

  • hjkle, w 로 이동하는 경우. 50j를 눌러서 50행 아래로 내려가는 경우는 그 중간과정이 보이지 않기 때문에 점프처럼 보이지만 일반 스크롤 이동해 해당합니다.
  • <C-F>, <C-B>로 이동하는 경우. 예를 들어 8<C-F> 라고 눌러 화면 8개 만큼을 아래로 스크롤한 것도 마치 점프처럼 보이지만, 실제로는 반복 스크롤입니다.
  • ft 로 특정 글자로 이동하는 경우.

대신 이런 동작들이 점프 위치에 기록됩니다.

  • 파일 처음이나 끝 혹은 특정한 행으로 이동한 경우 (gg, G)
  • 마크를 표시하는 동작
  • 특정 단어를 검색해서 이동하거나, 치환명령으로 치환한 경우 (검색,이동 후 치환함)
  • 특정 플러그인에서 점프 시켜주는 경우. (물론 이 경우에는 플러그인에서 커서를 이동시키기 전에 점프 리스트에 수동으로 위치를 삽입해줍니다.) 예를 들어 f 명령은 점프가 아니지만, “vim-easymotion” 플러그인을 사용하여 특정 글자 위치로 이동할 때에, 이 플러그인은 이동 전 위치를 m' 명령을 한 번 실행해주는 식으로 점프리스트에 기록해줍니다.

점프 리스트는 하나의 창에서 이동한 위치를 기록하기 때문에, 창 별로 하나씩 가지고 있을 수 있습니다.1창(window)은 버퍼를 표시하는 영역이라 생각하면 됩니다. 예를 들어 :split 명령으로 창을 분할했다면 새로운 창을 만든 것이 됩니다. 그리고 이 내용은 viminfo 파일에 기록되어 세션이 종료되어도 유지됩니다. 이 말의 의미는 우리가 vim을 시작했을 때, 점프리스트는 이전 실행의 기본 창의 위치를 기억하고 있다는 의미입니다.그래서 vim 을 실행한 직후 <C-o> 키를 두 번 눌러주면 이전에 vim을 닫기 전에 이동했던 위치로 갈 수 있습니다.

편집 리스트

버퍼의 내용을 편집할 때마다 Vim에는 되돌리기 이력이 추가되어 u 키를 눌러서 편집 이전 상태로 되돌릴 수 있습니다. 이 때 단순히 undo 내역만 저장되는 것이 아니라, 편집이 발생한 위치도 별도로 저장됩니다. jump list와 비슷한 이 목록을 변경 리스트(change list)라고 하며, 변경 리스트는 파일별로 관리되고, 각 파일별 변경리스트 역시 viminfo 에 기록되기 때문에 세션이 끝나도 유지됩니다. 변경 리스트 사이를 오가는 기능과 관련된 명령으로는 다음과 같은 것들이 있습니다.

  1. g; – 이전 변경 위치로 이동
  2. g, – 변경 리스트 내에서 다음 변경 위치 (더 최근의 편집위치)로 이동

편집 리스트를 통해서 이동하는 동작도 점프로 간주되어 점프 리스트에 추가 됩니다. 대신 같은 행에서 편집이 반복적으로 일어나는 경우, 같은 라인에서 발생하는 연속적인 변경은 매번 변경리스트에 기록되지는 않습니다.