[Vim] Vim사용시 Clipboard 정리

2023. 10. 13. 13:30Developers 공간 [Shorts]/Software Basic

728x90
반응형
<분류>
A. 수단
- OS/Platform/Tool : Linux, Kubernetes(k8s), Docker, AWS
- Package Manager : node.js, yarn, brew, 
- Compiler/Transpillar : React, Nvcc, gcc/g++, Babel, Flutter

- Module Bundler  : React, Webpack, Parcel

B. 언어
- C/C++, python, Javacsript, Typescript, Go-Lang, CUDA, Dart, HTML/CSS

C. 라이브러리 및 프레임워크 및 SDK
- OpenCV, OpenCL, FastAPI, PyTorch, Tensorflow, Nsight

 


1. What? (현상)

Ubuntu에서 Vim 을 사용하다 보면 복사 붙여넣기가 마음과 같이 잘 안 될 때가 있습니다.

 

그래서 Clipboard(클립보드)를 살펴보고자 하는데, OS의 클립보드란 Copy-Paste 과정에서 짧은 시간동안 데이터를 저장하는데 사용되는 "Software Program"입니다. 보통 GUI 환경의 일부이며, 환경안에 있는 프로그램으로 접근할 수 있는 "임시 메모리 블록"이기도 합니다.

 

vim을 사용하는 경우 선택한 것을 복사하거나 GUI를 활용하지 않으면 자체적인 레지스터를 통해 Copy-Paste가 가능하므로 Clipboard가 필요 없습니다. 그렇지만 우리는 "자유롭게 GUI로 복사하는 Clipboard를 Vim과 함께 쓰고 싶은 경우"에 대해 살펴보고자 합니다.

 

우리는 OS에는 어떤 clipboard가 있으며 vim(7.3 Version 이상)에서 해당 clipboard가 각각의 옵션에 따라 어떻게 작동하는지 확인하고자 합니다.


2. Why? (원인)

3가지 OS 클립보드를 살펴보겠습니다.

  • Microsoft Windows : 자체적인 Clipboard가 있어 복사시 사용할 수 있으며, "Clipboard History"라는 기능을 키면 Windows logo key + V를 활용해 여러개의 아이템을 붙여넣기 할 수도 있습니다.
  • OS X : 역시나 자체적인 Clipboard 가 있으며 복사시 사용할 수 있습니다.
  • Unix와 Linux 시스템 : X Window System을 사용하며, Selection이라는 것을 통해 클립보드를 제공합니다. 
    ** X Window System(X11) : Linux 혹은 Unix-like OS 등에서 사용되는 Graphical 인터페이스를 사용하기 위한 시스템 혹은 프로토콜 입니다.

그럼 Linux의 클립보드만을 자세히 살펴보겠습니다. X11 Graphical 환경은 여러개의 클립보드와 같은 버퍼를 가지는 데 이를 Selection이라고 합니다. 복사를 수행하면 데이터가 이 Selection 공간에 저장되며, 이를 직접적으로 활용해 볼 수 있는 방법이 있습니다. 바로 xclip이라는 툴입니다.

 

아래와 같은 명령어를 통해서 설치합니다.

# Ubuntu
sudo apt install xclip -y


# OS X
brew install xclip

selection은 4가지 종류가 있으며 아래 명령어로 확인할 수 있습니다.

xclip -help

Selection의 4가지 종류는 아래와 같습니다. 주로 사용할 selection은 빨간색으로 표시한 부분입니다.

  • PRIMARY : 현재의 선택된 텍스트를 담는 selection.
  • SECONDARY : 많이 사용되지 않음. PRIMARY와 CLIPBOARD와 별개로 사용하고 싶을 때 사용한다고 함.
  • CLIPBOARD : cut & copy & paste 명령어에 사용되는 일반적인 시스템 클립보드와 같은 selection.
  • BUFFER-CUT : 사실 Selection이라 불리지는 않으며, selection이 application에 소유되어 application 종류시 사라지는 것과는 달리, X-server가 정보를 가지고 있어 application이 종료되어도 유지됨.

아래는 xclip으로 복사하는 방법의 예 입니다.

echo "Hello World" | xclip -selection clipboard
cat data.txt | xclip -selection clipboard

아래 명령어를 통해 xclip으로 selection에 있는 복사된 내용을 확인할 수 있습니다.

xclip -selection clipboard -o

vim에는 10가지 레지스터가 존재합니다. 이중에 중요하게 살펴볼 레지스터를 빨갛게 표시했습니다.

  • The unnamed register “”
  • 26 Named registers “a to “z (or “A to“Z)
  • The small delete register “-
  • 10 numbered registers “0 to “9
  • The selection and drop registers “*(quotestar), “+(quoteplus), and “~
  • Three read-only registers “:, “., and “%
  • The alternate file register “#
  • The expression register “=
  • Last search pattern register “/
  • The black hole register “_

vim의 yank(y) 를 활용해 복사하거나 d,D,x,X,s,S,c,C 등을 활용해 삭제를 하면 어떤 특정 레지스터가 지정되어있지 않더라도 unnamed register를 채웁니다(즉, 가장 최근에 사용된 레지스터를 가리키고 있습니다). 또한 붙여넣기(p)를 실행시 이 레지스터를 활용하므로, 가장 많이 활용하게 되는 레지스터라고 생각하시면 됩니다.

 

한가지 상황을 보겠습니다. vim에 clipboard기능이 아예 꺼져 있을 수도 있습니다.

이는 아래 명령어로 확인할 수 있습니다.

vim --version
-clipboard

위와 같이 나온다면, 아마 vim을 설치했지만 설치된 것은 vim, vim-common, vim-runtime, vim-tiny정도만 설치되어있을 것이므로 시스템 클립보드를 지원하지 않습니다. 이런 상황에서는 앞서 말씀드린 unnamed register 가 사용되게 됩니다.

 

하지만 "GUI로부터 선택된 text"를 사용하거나 저장할 때는 clipboard가 필요하며 이때는 vim의 selection register라고 불리는 "*(quotestar) 레지스터"+(quoteplus) 레지스터를 활용하게 됩니다.

 

일단 위 상황을 살펴보기 위해, vim에서 GUI가 가능하게 만들려면 아래와 같이 설치합니다.

# vim-gtk or vim-gnome or gvim
sudo apt-get install vim-gtk -y

#Sometimes..
sudo apt-get install x11-xserver-utils

vim --version
+clipboard

이제 시스템 클립보드를 지원하는 것처럼 보입니다.

 

앞서 설명드린 두가지 selection register는 아래와 같이 다릅니다.

  • “*(quotestar) Register : 어떤 것을 선택하면 선택한 부분에 대한 정보를 담는 PRIMARY selection를 가리키는 레지스터
    • Drag해 선택한 부분들을 담는 클립보드
    • 아래와 같이 ~/.vimrc 파일에 우선적으로 원하는 클립보드를 셋팅을 할 수 있습니다.
# ~/.vimrc
set clipboard=unnamed
  • “+(quoteplus) Register : 어떤 것을 복사 했을 때의 정보를 담는 CLIPBOARD selection를 가리키는 레지스터
    • Ctrl+C혹은 Ctrl+V를 사용시 쓸 수 있는 클립보드
    • 아래와 같이 ~/.vimrc 파일에 우선적으로 원하는 클립보드를 셋팅을 할 수 있습니다.
# ~/.vimrc
set clipboard=unnamedplus

** WindowsMac OS X (Non-X11 System)에는 *레지스터와 +레지스터가 모두 시스템 클립보드를 가리키고 있습니다. 따라서 unnamed와 unnamedplus가 모두 같은 곳을 향하고 있다고 생각해도 됩니다.

** vim은 secondary selection에 접근하지 못합니다.


다양한 환경에서 Copy-Paste하는 여러가지 방법은 아래와 같이 정리할 수 있을 것 같습니다.

 

복사하는 방법

  • Vim : 두가지 방법 존재
    • shift+drag (OSX의 경우 option +drag)
    • virtual mode yank : y
      ** d,D,x,X,s,S,c,C,dd 등 삭제 명령어나 yy(한줄 복사) 등도 동일합니다.
  • Tmux : shift+drag (OSX의 경우 option +drag)
  • Bash : shift + drag(OSX의 경우 option +drag), drag
  • Normal : ctrl +c (OSX의 경우 option +c)

붙여넣는 방법

  • Vim : 두가지 방법 존재
    • shift+insert (OSX의 경우 불가능)
    • virtual mode yank : p
  • Tmux : shift+insert (OSX의 경우 불가능)
  • Bash : shift + insert (OSX의 경우 불가능)
  • Normal : ctrl +v (OSX의 경우 option+v)

위를 활용해 Linux에서 Copy-Paste를 실행한 실험결과는 아래와 같습니다. 복사를 한 후에 붙여넣기가 가능했던 경우들을 정리해보았습니다. (참조만 하세요)

Copy( → )
Paste( ↓ )
Vim
(shift+drag)
Vim
[Unnamedplus]

(y)
Tmux
(shift+drag)
Shell
(shift+drag)
Normal
(ctrl+c)
Vim
(shift+insert)
O   O O O
Vim
[UnnamedPlus]

(p)
  O     O
Tmux
(shift+insert)
O   O O O
Shell
(shift+insert)
O   O O O
Normal
(ctrl+v)
  O     O

 


3. How? (해결책)

그렇다면 위와 같이 Linux에서 vim 등 다양한 상황이 주어지면, 복사와 붙여넣기를 할 때 어떤 Clipboard를 사용하게 될지 정리해두고자 합니다.

1. Linux 

<복사시>

 
Vim
(shift+drag)
Vim
(y)


Tmux
(shift+drag)

Shell
(shift+drag)

Normal
(ctrl+c)
 unnamed unamedplus
Location PRIMARY  PRIMARY CLIPBOARD PRIMARY PRIMARY PRIMARY+CLIPBOARD

<붙여넣기시>

 
Vim
(shift+insert)

Vim
(p)

Tmux
(shift+insert)
 
Shell
(shift+insert)
 
Normal
(ctrl+v)
unnamed Unnamedplus
Location PRIMARY PRIMARY  CLIPBOARD PRIMARY PRIMARY CLIPBOARD

** 위실험에는 한가지 조건이 있습니다. vim과 tmux가 실행된 pc가 같은 pc 일때 입니다. 예를 들어 tmux를 실행한 pc A에서 다른 서버 pc B로 접근시 해당 서버에서 vim을 실행하면 같은 클립보드를 공유하기 어렵습니다. 왜냐면 위의 경우 tmux에서는 pc A의 클립보드를 사용할 것이고, pc B에서 실행한 vim은 본인의 클립보드를 사용할 것이기 때문입니다. 이것은 방법이 없습니다.

** 단, docker instance 안과는 이를 공유 할 수 있습니다. X11 환경 변수 및 DISPLAY 파라미터 등을 docker instance에 전해준다면 docker안에서도 밖에 있는 clipboard를 공유할 수 있게 하는 것 입니다.


2. OSX의 경우

<복사시>

 
Vim
(shift+drag)
Vim
(y)


Tmux
(shift+drag)

Shell
(shift+drag)

Normal
(ctrl+c)
 unnamed unamedplus
Location CLIPBOARD CLIPBOARD CLIPBOARD CLIPBOARD CLIPBOARD CLIPBOARD

<붙여넣기시>

 
Vim
(shift+insert)

Vim
(p)

Tmux
(shift+insert)
 
Shell
(shift+insert)
 
Normal
(ctrl+v)
unnamed Unnamedplus
Location X CLIPBOARD  CLIPBOARD X X CLIPBOARD

 


 

위에서 보시다시피 tmux는 항상 PRIMARY selection에서 동작하는 것처럼 보이는데, 사실 자체 Copy 버퍼를 가지고 있지만 아래와 같이 tmux와 vim을 vi-style key-binding으로 연결 했기 때문에 동작하는 것입니다. 

 

이를 가능하게 하기 위해서는, 아래와 같은 셋팅을 ~/.tmux.conf에 추가해줍니다.

# ~/.tmux.conf

setw -g mode-keys vi
unbind -Tcopy-mode-vi Enter
bind-key -T copy-mode-vi 'v' send -X begin-selection
bind-key -T copy-mode-vi 'V' send -X select-line
bind-key -T copy-mode-vi 'r' send -X rectangle-toggle
bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel 'xclip -sel clip -i'

 

Mac OS의 경우는 xclip이 없으므로 reattach-to-user-namespace프로그램을 활용해 연결할 수 있습니다. 먼저 이를 설치합니다.

brew install reattach-to-user-namespace

그 다음, zsh인 경우 아래와 같은 셋팅을 ~/.tmux.conf에 추가해줍니다.

# ~/.tmux.conf

# For start reattach-to-user-namespace
set -g default-command "reattach-to-user-namespace -l zsh"

setw -g mode-keys vi
unbind -Tcopy-mode-vi Enter
bind-key -T copy-mode-vi 'v' send -X begin-selection
bind-key -T copy-mode-vi 'V' send -X select-line
bind-key -T copy-mode-vi 'r' send -X rectangle-toggle
bind -T copy-mode-vi 'y' send -X copy-pipe-and-cancel "reattach-to-user-namespace pbcopy"
더보기

--------------------------------------------------------------------------------

** tmux가 2.5 version 미만인 경우 스타일

bind -t vi-copy y copy-pipe 'xclip -in -selection clipboard'

** tmux가 2.5 version 이상인 경우 스타일

bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel 'xclip -in -selection clipboard'

--------------------------------------------------------------------------------


 

728x90
반응형