Vim에서 삭제는 잘라내기로 동작한다. OS에서 복사한 값을 붙여넣기 전 텍스트를 정리하며 제거된 값이 OS에서 복사한 값을 지워버린다. 왜냐면 잘라내기로 동작하기 때문이다. 이 불편함을 어떻게 해결할 수 있을까?
Vim 클립보드 내용을 검색하면 다들 OS 클립보드 연동하는 방법만 있지 Vim에서 삭제 시 OS 클립보드 값을 지키는 내용은 없더라. 나만 불편한 것인가...?
문제 원인
보통 set clipboard=unnamedplus
설정하여 OS ↔ Vim 클립보드를 동기화 한다.
OS ↔ Vim 클립보드와 연결만 하면 복사, 붙여넣기 시 매번 "+y
, "+p
같이 +
, *
레지스터 지정해야 해서 불편하다.
set clipboard=unnamedplus
문제는 OS에서 복사한 값이 dd
, x
같이 Vim
제거 동작 시 사라진다는 것이다.
상황에 따라 다르지만 보통 복사 후 붙여넣기 전까지 입력도 하고 삭제도 하며 텍스트 가공이 이루어지는데 삭제를 해버리면 OS 클립보드 값이 사라져서 곤란하다.
Vim
의 0
번 레지스터는 삭제가 이루어져도 유지되는 것과 다르다. 이유는 OS ↔ Vim 클립보드를 동기화했기 때문에 삭제하는 것도 OS에 동기화하면서 발생한다.
문제 해결을 위해선 OS의 값을 붙여넣기 전까지 블랙홀 레지스터로 OS에서 복사한 값을 잘 유지해야 한다.
해결 방법
손쉽게 블랙홀 레지스터로 보내기
블랙홀 레지스터 단축키 입력이 생각보다 많이 불편하다.
그래서 처음에는 블랙홀 레지스터를 손쉽게 보내도록 키 맵핑을 했다.
" 블랙홀 레지스터 쉽게 호출할 수 있도록 맵핑
nnoremap <Space>x "_x
vnoremap <Space>x "_x
nnoremap <Space>X "_X
vnoremap <Space>X "_X
nnoremap <Space>s "_s
vnoremap <Space>s "_s
nnoremap <Space>S "_S
vnoremap <Space>S "_S
nnoremap <Space>c "_c
vnoremap <Space>c "_c
nnoremap <Space>C "_C
vnoremap <Space>C "_C
nnoremap <Space>d "_d
vnoremap <Space>d "_d
nnoremap <Space>D "_D
vnoremap <Space>D "_D
nnoremap <Space>dd "_dd
vnoremap <Space>dd "_dd
삭제와 잘라내기 동작 구분
하지만 이것 또한 귀찮다.
근본적으로 Vim의 레지스터 동작이 보편적으로 사용되는 OS과 달라서 생긴 문제라고 생각이 들었다. 삭제 != 잘라내기
인데 Vim은 삭제 = 잘라내기
동작을 하니 말이다. 그래서 잘라내기만 동작하도록 명시적으로 키 맵핑을 지정해서 해결했다.
--
--
-- 명시적인 호출 시에만 삭제 레지스터로 이동
-- 삭제를 하더라도 OS 클립보드 값을 보호하기 위함
-- 기본적으로 삭제는 블랙홀 레지스터 사용
vim.keymap.set("n", "d", '"_d')
vim.keymap.set("v", "d", '"_d')
vim.keymap.set("n", "D", '"_D')
vim.keymap.set("v", "D", '"_D')
vim.keymap.set("n", "dd", '"_dd')
vim.keymap.set("v", "dd", '"_dd')
vim.keymap.set("n", "x", '"_x')
vim.keymap.set("v", "x", '"_x')
vim.keymap.set("n", "X", '"_X')
vim.keymap.set("v", "X", '"_X')
vim.keymap.set("n", "s", '"_s')
vim.keymap.set("v", "s", '"_s')
vim.keymap.set("n", "S", '"_S')
vim.keymap.set("v", "S", '"_S')
vim.keymap.set("n", "c", '"_c')
vim.keymap.set("v", "c", '"_c')
vim.keymap.set("n", "C", '"_C')
vim.keymap.set("v", "C", '"_C')
-- Space + 삭제 입력 시 원래 동작(클립보드 사용) 유지: 잘라내기 동작
vim.keymap.set("n", "<Space>d", "d")
vim.keymap.set("v", "<Space>d", "d")
vim.keymap.set("n", "<Space>D", "D")
vim.keymap.set("v", "<Space>D", "D")
vim.keymap.set("n", "<Space>dd", "dd")
vim.keymap.set("v", "<Space>dd", "dd")
vim.keymap.set("n", "<Space>x", "x")
vim.keymap.set("v", "<Space>x", "x")
vim.keymap.set("n", "<Space>X", "X")
vim.keymap.set("v", "<Space>X", "X")
vim.keymap.set("n", "<Space>s", "s")
vim.keymap.set("v", "<Space>s", "s")
vim.keymap.set("n", "<Space>S", "S")
vim.keymap.set("v", "<Space>S", "S")
vim.keymap.set("n", "<Space>c", "c")
vim.keymap.set("v", "<Space>c", "c")
vim.keymap.set("n", "<Space>C", "C")
vim.keymap.set("v", "<Space>C", "C")
이렇게 하면 아래의 장/단점을 가지게 된다.
- 장점
- 보편적인 OS에서 사용하는 것과 동일하게 클립보드 관리 가능
- 복사한 것은 다른 복사가 오거나 잘라내기 전까지 유지된다.
- 삭제는 삭제다.
- 잘라내기 시 해당 값으로 복사 값이 변경된다.
- 단점
- Vim에서 삭제 시
"1
~"9
으로 저장되는 삭제 히스토리를 사용하지 못함 - 개인적으로는
"1
~"9
을 사용한 적이 거의 없다. 코딩하면서 삭제는 워낙에 빈번하게 일어나기에 기억도 안난다. 설령 제거한 적을 저장하고 싶다면 명시적으로 레지스터를 할당에서 저장하는 것이 관리도 기억도 잘 될 것이라고 생각한다. - macOS의 경우 RayCast를 통해서 클립보드 히스토리 관리가 가능하기 때문에 기능 보안도 가능하다.
- Vim에서 삭제 시
마무리
삭제와 잘라내기 동작을 구분하도록 키 맵핑 후 한동안 삭제 후 왜 삭제 레지스터에 값이 들어가지 않았지? 하고 해매고 있다.
적응이 되면 편해질 것 같지만 꼭 이렇게 Vim 동작을 바꿔야하나 생각이 든다.