14 Vim 심화 - Macro (매크로)
- vim
- 2021. 12. 18.
드디어 Vim 의 궁극기 Macro 를 살펴볼 차례다.
Vim 매크로
Macro 는 Vim 명령어'들'을 기록하고, 이를 반복할 수 있는 기능이다.
이전에 Vim Micro Macro(dot command)를 활용해서 이전 명령을 바로 반복할 수 있었다. 그러나, 이는 이전 명령을 반복할 뿐, '이동 후 명령' 과 같은 작업에 대해서는 그 반복이 불가능하다.
매크로가 필요한 순간
가령 다음 스크린샷의 좌측과 같은 코드가 있다고 가정해보자. 이를 오른쪽 코드와 같이 바꾸고자 한다. javascript 에서 key 를 그대로 value 에 넣은 뒤 이를 대문자로 바꾸려고 한다.
일단, jazz 가 포함된 라인(2번줄)에서 vim 을 활용하여 이 과정을 진행해보자.
다음과 같이 기존 코드를 변경할 것이다.
// from
jazz: ""
// to
jazz: "JAZZ"
이를 수행하기 위한 시퀀스는 다음과 같다.
- jazz 의 j 로 커서를 이동한다. (
^
) - 단어를 복사한다. (
yiw
) - 첫 번째 따옴표로 이동한다. (
f"
) - 복사한 단어를 붙여넣는다. (
p
) - 붙여넣어진 단어를 대문자로 변경한다. (
gUaw
)
*참고:gU{모션}
은 모션 범위를 대문자로 변경한다.gu
는 소문자로. - 아래 줄로 이동한다. (
j
)
위에서 설명한 1~6 과정이 그대로 반복된다면 opera 가 포함된 라인에도 동일한 동작이 수행되게 할 수 있다.
차라리 노가다를 택할 수도 있고, 굳이 매크로를 쓰지 않아도 적절히 몇번 반복하면 끝난다고 생각할 수도 있겠지만, 동일한 작업을 해야하는 라인이 수십줄이 넘어간다고 상상해보자.
매크로를 활용하지 못한다면, 각 라인마다 각각 12회의 키를 입력해야 한다.
일련의 동작들을 기록하고 재사용할 수 있다면 어떨까? 그게 바로 Vim Macro 이다.
Vim Macro
Vim 에서 매크로 등록하고 실행하기
q{레지스터}
로 매크로 기록 시작q
로 매크로 기록 종료@{레지스터}
로 저장된 매크로 실행@@
로 직전에 실행한 매크로 재실행{반복횟수}@{레지스터}
또는{반복횟수}@@
로 저장된 매크로를 '반복횟수' 만큼 재실행
💡 레지스터는 알파벳(a-z) 또는 숫자(0-9)를 지정할 수 있다. 매크로가 저장되는 레지스터는 복사, 잘라내기 등의 명령에 의해 저장되는 공간과 동일한 공간을 사용하기 때문에 주의하여야 한다. 또한 이를 활용하여 의도적으로 매크로의 내용을 수정할 수도 있다. (아래 [매크로 수정하기] 참고)
q - Vim Macro 기록하기 & 기록 종료하기
Normal Mode 에서 q
를 입력하면, 하단 상태표시줄에 q 가 표시된다. 이는 앞으로 기록할 레지스터를 지정해주기를 대기하고 있는 상태이다. 레지스터(a-z, 0-9 중 하나)를 정하여 입력하면 상태표시줄에 'Recording @a'(레지스터로 'a'를 입력했다고 가정) 와 같이 실제 명령어를 대기하고 있는 상태가 된다.
일련의 동작들을 입력한 뒤 다시 q
를 입력하면 매크로 기록이 종료된다.
다음 스크린샷에서 위에서 1~6 과정에서 입력한 과정들을 매크로로 기록하는 과정을 살펴보자.
이 예제에서는 매크로를 기록할 레지스터로 a 를 사용했다.
@ - Vim Macro 실행하기
@{레지스터}
로 특정 레지스터에 저장된 매크로를 실행시킬 수도 있고, @@
로 직전에 실행한 매크로를 재실행할 수도 있다.
"opera" 라인(3번줄)은 @a
로 재실행해보자. 이전 스크린샷에서 그대로 이어진다.
rock 라인은(4번줄)은 @@
로 직전에 실행한 매크로를 반복해보자. 이전 스크린샷에서 그대로 이어진다.
(@ 이 두 번 눌러진다는것을 보여주기 위해 @과 @ 사이에 약간의 딜레이를 주었다.)
이렇게 매크로를 알아보았다. 사실 이렇게 매크로를 활용하는 것이 거의 전부이다. (쓸 데 없을지도 모르지만) 매크로와 관련하여 몇가지 사항을 아래에서 더 알아보도록 하자.
레지스터에 저장된 매크로 확인해보기
vim 에서는 레지스터에 저장된 내용을 확인하기 위한 command mode 명령어를 제공한다. :register
가 그것이다. 단순히 이 명령어를 입력하면 모든 레지스터의 저장된 값들을 리스팅해준다. ':register' 명령어는 인자를 받기도 하는데, :register a
와 같이 명령어의 인자로 레지스터명을 전달하면 해당 레지스터에 저장된 값을 표현해준다. (오리지널 vim 에서도 UI 만 다를 뿐 VSCode Vim 과 동일하게 동작한다.)
레지스터에 저장된 내용이기 때문에, 당연하게도 "ap
명령어로 a 레지스터의 내용을 붙여넣을 수 있다. (이게 가능한 이유가 궁금하다면 2021.11.14 - [개발도구/vim] - [The Vim Way] 06 Vim 기본조작 - Vim 복사하기와 붙여넣기 그리고 레지스터 를 참고하도록 하자.)
매크로는 레지스터에 저장된다는 점을 활용하여 복잡한 매크로의 경우 .vimrc 등의 파일에 등록하여 관리하기도 한다.
매크로 수정하기
- 매크로 기록하기
- 매크로를 기록한 레지스터의 내용을 새로운 라인에 붙여넣기 (
"{레지스터}p
) - 매크로 내용 일부 수정하기
- 수정한 매크로를 레지스터에 등록하기 (한 줄을 전부 지우면서 등록한다면
"{레지스터}
dd
) - 매크로 실행하기
레지스터는 yanking(복사) 또는 잘라내기 등이 수행되어 저장되는 레지스터와 동일한 공간을 사용한다. 바로 위 [레지스터에 저장된 매크로 확인해보기]에서 살펴본 것처럼 레지스터에 저장된 내용을 확인할 수 있는데, 레지스터에 텍스트를 등록하는 기능(가령 복사나 삭제)을 활용하여 매크로를 수정할 수 있다. 위 리스트에서는 한 줄 삭제(dd
)를 활용하여 수정한 시퀀스를 다시 레지스터에 등록하는 과정을 보여주고 있다.
Vim Macro 활용하기
반복자와 함께 활용하기
매크로도 하나의 명령이기 때문에, 매크로를 실행하기 전에 반복횟수를 지정할 수 있다.
단어와 단어는 tab 문자로 구분되어있는 다음과 같은 데이터가 있다.
1 one first
2 two second
3 three third
4 four fourth
5 five fifth
6 six sixth
7 seven seventh
8 eight eighth
9 nine ninth
10 ten tenth
11 eleven eleventh
12 twelve twelfth
13 thirteen thirteenth
14 fourteen fourteenth
15 fifteen fifteenth
16 sixteen sixteenth
17 seventeen seventeenth
18 eighteen eighteenth
19 nineteen nineteenth
20 twenty twentieth
21 twenty-one twenty-first
22 twenty-two twenty-second
23 twenty-three twenty-third
24 twenty-four twenty-fourth
25 twenty-five twenty-fifth
26 twenty-six twenty-sixth
27 twenty-seven twenty-seventh
28 twenty-eight twenty-eighth
29 twenty-nine twenty-ninth
30 thirty thirtieth
31 thirty-one thirty-first
40 forty fortieth
50 fifty fiftieth
60 sixty sixtieth
70 seventy seventieth
80 eighty eightieth
90 ninety ninetieth
100 one hundred hundredth
이 데이터를 가공하여 각 라인을 다음과 같이 처리하고자 한다.
// from
1 one first
// to
const ONE = 1; // first number
이를 매크로를 기록하고 모든 라인에 적용해보도록 하자.
먼저 기록하는 화면을 보도록 하자.
이제 이 매크로를 나머지 라인들에 적용해보자.
이와 같이 '충분한' 숫자를 반복횟수로 지정하여 남아있는 처리 대상에 대해 매크로가 적용되게 할 수 있다. 매크로는 더 이상 진행될 수 없으면 그 동작을 멈추므로 실제로는 37 라인밖에 되지 않지만, 100@@
와 같이 '충분한' 반복횟수를 지정하는 것으로 편리하게 '나머지 대상 전부'를 지정할 수 있다.
위 스크린샷의 경우처럼 100 의 경우 그 처리가 제대로 되지 않은것을 확인할 수 있는데(one hundred 만 이름 사이에 공백이 들어가있음), 매크로를 기록할 때 이러한 다양한 상황까지 고려하여 작성해주어야 할 필요가 있을 수 있다.
매크로는 동일한 이름을 공유하는 마이크로 매크로(dot command)보다는 그 활용도가 낮다고 할 수 있다. 매크로는 위에서 본 것과 같이 '복잡한 시퀀스'를 '여러번 수행'하여야 할 때 그 진가를 발휘한다. 간혹 코딩을 하다보면, 이러한 요구사항이 생기기 마련인데, 그럴 때마다 vim 에서 macro 를 어떻게 수행했는지 검색해보면 그만이다. 그러니 부담을 갖지 말고, 그러한 상황에 매크로가 있었다는 사실을 기억하고 적용해볼 수 있었으면 좋겠다.
다음 시간에는 커맨드모드에서 수행할 수 있는 다양한 명령어 중에 하나인 (그리고 사실 이 연재에서 다루는 몇 안되는 커맨드모드 명령어중에 하나인) '찾아바꾸기' 기능을 소개하도록 하겠다.
'vim' 카테고리의 다른 글
16 Vim 심화 - Surround (1) | 2021.12.20 |
---|---|
15 Vim 심화- 찾아 바꾸기 (substitute) (0) | 2021.12.20 |
13 Vim 기본 - 기본편 요약, 치트시트, 커리큘럼 (5) | 2021.12.06 |
12 Vim 기본 - undo(되돌리기), redo(재실행) (0) | 2021.12.05 |
11 Vim 기본 - 명령 n번 반복하기 (0) | 2021.12.05 |