8 minute read

VIM

:wq 또는 :q!가 그저 힙해보인다는 이유로, 그리고 리눅스를 사용하게 되면 결국 웬만하면 다 설치되어 있고, 그렇지 않더라도 설치하기 쉬운 vim을 쓰는 게 편하다는 명분으로 입문한지 5년은 더 지난 듯하다. 사실 처음 붙잡고 공부했을 때에는 .vimrc의 수많은 스크립트들을 이해하고 써먹기는커녕 어찌어찌 친절한 블로거의 예시를 그대로 가져다 쓰며 hjkl를 비롯한 기본 중의 기본이 되는 키맵들을 익히기에 바빴다. 코딩 공부보다 코딩을 위한 에디터 공부가 더 힘들 지경이었다.

그 과정을 겪고 나니, 확실히 괜히 있어보이고 또 실제로도 꽤나 생산성 있게 vim으로 코드를 작성할 수 있게 되었다. 그러나, 딱 거기까지였다. 더 제대로 된 기능을 써먹기에는 내 능력이 부족했고, 그저 평범한 에디터에서는 잘 쓰이지도 않는 구닥다리 키맵이 손에 익어버려 다른 에디터 쓸 때 헷갈리기나 하는 신세가 되어버렸다. 그렇게 그 당시 내 나름의 능력치 안에서 픽스드포인트에 도달해버리니, 굳이 vim을 그대로 써먹어야 할 필요가 있나 싶어 다른 에디터를 사용하기 시작했다. 얼마 지나지 않아 정착한 것이 vs code였다. 물론 에디터를 옮긴 뒤에도 손에 익은 습관은 버리지 못해, vs code에 vim extension을 설치해 최소한의 키맵과 모드들은 사용할 수 있도록 하여 오묘한 시너지 효과를 즐기는 편이었다.

그렇게 vs code로 정착한지도 꽤 되었는데, 갑자기 오늘 vim을 사용하고 싶어졌다. 정확히는 vs code에 이미 있음에도 단축키가 익지 않아 잘 쓰지 않던 기능들이, 오히려 vim에서 빠르게 사용 가능하다는 것을 알게 되어 다시 한 번 제대로 세팅해보고 싶어진 것이다.

그렇게 또다시 삽질이 시작됐다.

NEOVIM

이번에는, 지난번에 그냥 블로거가 좋다길래 아무 생각 없이 설치하고 사용했던 neovim을 사용해 세팅을 마무리하기로 하였다. Neovim만의 여러 장점이 있다고 하는데, 사실 아직도 잘 모르겠다. 그냥 요즘 플러그인들은 neovim을 많이들 타겟팅하고 있어 보였고, vim에서 될만한 웬만한 것들은 neovim에서도 되기에 그렇게 결정하였다.

Neovim은 다음과 같이 간단하게 설치 가능하다:

sudo apt install neovim

간혹 최신 릴리즈가 설치되지 않는 경우도 있는데, 최신 릴리즈가 꼭 필요하다 싶으면 neovim의 깃허브 레포에 있는 최신 릴리즈 버전을 다운받은 뒤 설치하면 된다. 현재 최신 버전인 0.7.2버전으로 예를 들면, 다음과 같이 진행하면 된다:

wget https://github.com/neovim/neovim/releases/download/v0.7.2/nvim-linux64.deb
sudo apt install ./nvim-linux64.deb

(*주의: 이미 위의 방식으로 neovim을 설치한 적 있다면, 여러 dependency 때문에 아래 방식으로 설치할 때 문제가 생길 수 있다. 다 깨끗하게 지우고 시도하자)

Neovim 설치가 끝났다면, 다음의 작업도 수행해 neovim의 여러 파이썬을 활용하는 기능들을 문제없이 사용할 수 있도록 하자:

pip install neovim

(*당연히 python 및 pip은 진작 설치되어 있어야 한다)

나 같은 경우는, 추가로 본인의 쉘 프로파일(~/.bashrc, ~/.zshrc, ~/.bash_profile, etc.)에 alias vi='nvim'을 추가하여 로그인시 vi 커맨드를 실행했을 때 자연스럽게 neovim이 실행되도록 하였다.

.vimrc, colors, vim-plug

이제 vim을 내 입맛대로 고쳐야 할 시간이다. 아무래도 새로운 컴퓨터에서 세팅을 해야 하거나 새로운 서버에도 정성껏 나의 세팅대로 vim을 사용하고 싶었기 때문에 나만의 세팅을 내 깃허브 레포로 올려 두었다. Vim을 쓰다 nvim으로 옮기면 몇가지 디렉토리 세팅도 다시 해줘야 하기에, 차근차근히 순서대로 기록해 두고자 한다.

가장 먼저 알아둬야 할 것은, neovim 환경설정을 위한 디렉토리 구조이다. Neovim은 보통 ~/.config/nvim/ 디렉토리 아래에 여러 세팅용 파일 및 디렉토리들을 담아둔다. 이는 주로 ~/.vim 디렉토리에 플러그인과 컬러테마들을 저장해 두고 ~/.vimrc로 여러 설정을 하던 vim과는 조금 다른 구조이다. 그래서 일단 기존의 vim을 세팅하던 때와 같은 환경에서 자연스럽게 neovim 세팅을 하기 위해, neovim의 설정파일 경로인 ~/.config/nvim/init.vim~/.vimrc로 링크 걸어두고, 컬러테마 폴더 경로인 ~/.config/nvim/colors/~/.vim/colors/로 링크 걸어뒀다. 굳이 이렇게 할 필요는 없는 걸로 알기에, 해당 부분은 재량껏 넘어가도 좋다. (*주의: 당연히 원본 파일들이 있어야 문제없이 링크가 된다. 나는 이미 숱한 삽질 끝에 어느정도 안정적인 세팅을 깃허브 레포에 담아두었기에 여기 있는 파일들을 먼저 홈 디렉토리에 경로에 맞게 옮겨준 뒤 링크를 걸어준다)

ln -s ~/.config/nvim/init.vim ~/.vimrc
mkdir .vim
ln -s ~/.config/nvim/colors ~/.vim/colors

*주의: 어쩔 수 없이, 세팅 과정이 많이 꼬여있다. 원래 정석대로라면 무언가 필요한 패키지나 바이너리들을 먼저 설치하고 그에 맞춰 .vimrc를 수정해야 하는데, 한 번 세팅한 채로 쭉 써먹기 위해서는 그런 과정이 무시될 수밖에 없다. 그렇기에 중간중간 커맨드 에러가 나더라도 무시하고 아래 적힌 순서대로만 따라하면 큰 문제가 없게 완료되도록 기록을 해 두겠다.

참고로, .vimrc에서 해둔 세팅이 뭔지를 알아야 다음 단계가 이해되기 때문에, 간단하게 정리해 두겠다. 세팅은 크게 다음과 같이 나눠진다.

  1. 아주 기본적인 세팅 (기존의 vi 환경을 사용할지, 탭은 어떻게 쓸지, 들여쓰기는 어쩔지, 라인넘버는 어떻게 표시할지 등등)
  2. 유용한 키맵들 (<leader> 키 설정 및 플러그인과 관계 없이 적용할 여러 키맵들)
  3. 플러그인들 (vim-plug 사용)
  4. 각종 플러그인들에 대한 세부 세팅들

아무래도 누군가 나의 .vimrc를 가져다 쓴다면, 2번까지는 일단 복붙해서 쓰더라도, 3번부터는 본인 입맛에 맞게 취사선택하는 게 좋을 것이다. (*아래에서도 주기적으로 강조하겠지만, 안 그러면 에러 투성이의 vim을 맛보게 될 것이다. 예를 들어, 4번 항목에서 OPAM 및 OCaml 사용을 위해 opam user-setup을 통해 자동으로 추가한 여러 스크립트들이 포함되어 있는데, 이는 OPAM의 버전이 2.1일 때 제대로 돌아가질 않는다. 그래서 어쩔 수 없이 본인의 쉘 프로파일에 export OPAMCLI=2.0을 추가해 줘야 문제가 안 생기는데, 이를 알아내는 과정도 그리 순탄치는 않았다.)

이제 다음 단계이다. 여기까지만 와도 사람처럼 쓸 수 있는 에디터가 되지만, 사실 요즘의 빵빵한 에디터들 사이에서 경쟁력을 가지기 위해서는 아직 여러모로 부족하다. 코드 자동완성이라든가, 린터나 포매터 같은 것들을 사용하기 위해서는 플러그인이 필요하다.

가장 먼저(뒤에서 설치할 어떤 플러그인 때문에), 최신 버전의 node.js가 필요하다. 알아서 잘 설치하면 되는데, 웬만하면 nvm을 이용하도록 하자. 아마 위 링크를 들어가 보면 설치 및 사용 방법이 매우매우 친절하게 나와 있기 때문에, 굳이 여기에 다시 적어두진 않겠다. 무언가 업데이트 되면서 커맨드가 바뀔 수도 있지 않은가.

그리고 .vimrc의 중간에 예쁜 컬러테마를 위해 colo zenburn을 추가해 뒀는데, 이를 사용하기 위해서는 ~/.config/nvim/colors (또는 링크한 ~/.vim/colors) 디렉토리 안에 zenburn.vim 파일이 있어야만 한다. 나는 이 링크에서 받아서 넣어줬다.

이제 정말 플러그인을 설치해 보도록 하자. 나 같은 경우에는 vim-plug를 사용한다. 개인적으로 가장 쉽고 간편하게 플러그인 관리가 가능하며, 대부분의 유명한 플러그인들은 vim-plug로 플러그인을 설치할 수 있도록 제공해주고 있기 때문이다. 이를 사용하기 위해, 따로 설치를 해줘야 한다. 아마 위 링크를 들어가 보면 매우매우 친절하게 나와 있기 때문에, 굳이 여기에 다시 적어두진 않겠다. 무언가 업데이트 되면서 커맨드가 바뀔 수도 있지 않은가.

위를 설치한 뒤에, 다시 vi ~/.vimrc를 통해 .vimrc를 열어보자. 사실 아무 파일이나 열어도 되긴 하지만, 세팅을 확인하면서 플러그인을 설치하면 좋으니까 같이 열어서 보자. nvim이 열린 상태로 :PlugInstall을 입력하면, .vimrccall plug#begin('~/.vim/plugged') 아래부터 call plug#end() 위까지 적혀있는 플러그인 목록들이 쭉 설치된다. 눈치가 빠르다면 보이겠지만 ~/.vim/plugged/ 디렉토리에 플러그인들을 설치하기 때문에 기존 vim 사용자들도 자연스럽게 사용 가능하며, 혹시 ~/.vim 디렉토리를 굳이 따로 만들고 싶지 않다면 해당 부분의 경로를 바꿔주면 될 것이다.

아마 웬만하면 문제없이 모든 플러그인이 빠르게 설치될 것이다. 이후 vim을 종료했다가 다시 열면 플러그인이 적용된 상태라고 보면 된다.

이제 정말 중요하고도 어려운 설정이 남았는데, 바로 coc.nvim이다. 조금 전 vim-plug를 통해 잘 설치가 되었을 거라 기대하는데, 사실 내 vim-setup에서 바로 파일을 복붙했다면 지금까지의 과정에서 vim을 새로 열 때마다 커맨드 에러가 떠서 애를 먹었을 것이다. 그러니까 막 복붙하지 말고 차근차근히 해야 무탈한 것이다. 물론 커맨드 에러는 무시하면 되므로 내가 새로운 컴퓨터에 세팅할 때에는 그냥 복붙한다. 또한 node.js를 설치해야 하는 이유도 이 coc.nvim 때문이기에, 반드시 순서를 지켜 node.js를 설치한 후에 :PlugInstall을 해줘 coc.nvim 설치 과정에 문제가 없도록 하자.

아무튼 coc.nvim 플러그인 자체는 이미 설치가 완료되었을텐데, 이를 진짜 제대로 사용하기 위해서는 아주 복잡해 보이는 세팅 스크립트를 .vimrc에 추가해야 하며, 또 여러 필요한 coc extension들을 설치해 줘야 한다. 일단 coc.nvim에서 설치하라고 권장하는 coc-json과 coc-tsserver를 설치해 주도록 하자. Neovim을 열어 :CocInstall coc-json coc-tsserver를 입력하면 설치가 진행된다. 추가로 필요한 extension들을 찾아서 설치하면 되는데, 나는 주로 OCaml, Python, C/C++을 다루기 때문에 coc-pyright, coc-clangd를 더 설치해 주고 :CocConfig 커맨드를 통해 coc-settins.json 파일을 다음과 같이 수정해 줬다:

{
    "languageserver": {
        "ocaml-lsp": {
            "command": "opam",
            "args": ["config", "exec", "--", "ocamllsp"],
            "filetypes": ["ocaml", "reason"]
        }
    },
    "coc.preferences.currentFunctionSymbolAutoUpdate": true
}

(추가) Copilot

Copilot이 상용화되면서, 친절한 GitHub는 neovim에서 copilot을 사용할 수 있도록 플러그인을 제공해 주었다. 세팅도 매우매우 간단한데, 몇가지 메모사항이 있어 추가한다. 참고로 내 경우에는 GitHub Education에서 학생 인증을 통해 student pack을 제공받아 copilot을 사용중이다.

Copilot 서비스를 제공받기 위한 과정은 알아서 개인적으로 했다 치고, copilot을 사용 가능한(구독중인) GitHub 계정이 준비되어 있다고 하자. 이제 neovim에서 이를 사용하기 위해서는 플러그인을 추가해야 한다. .vimrc 파일을 열어 지금까지 플러그인을 추가했던 방법대로 github/copilot 플러그인을 추가하면 된다. 즉 Plug 'github/copilot.vim' 한 줄만 추가해 주면 된다. 당연히 내 .vimrc에는 추가해 뒀다.

그 뒤에 vim을 연 뒤 :Copilot setup 커맨드만 입력하면 된다. 이 때 계정 연동 및 인증을 위해 인증 코드를 띄워주고 엔터를 입력하면 브라우저를 통해 인증 페이지를 열기 시도한다. 만약 리눅스 서버 등의 환경에서 작업하는 중이라면 브라우저를 열지 못해 실패 메시지가 뜰텐데, 당황하지 말고 이 때 뜨는 링크로 직접 브라우저를 열어 접속한 뒤, 인증 코드를 입력해 인증해 주면 된다.

사실 이것만으로 copilot을 사용하기 위한 준비는 끝났다. 바로 아무 파일이나 열어 코드(아니면 논문이라도)를 작성해 보자. 대충 입력한 뒤 적당히 커서를 두고 입력을 하다가 말면, 입력하던 부분에 이어서 회색 텍스트가 뜰 것이다. Copilot의 추천 텍스트이다. 만약 다른 세팅을 건드리지 않았다면, 여기서 <tab>을 입력하면 추천해준 텍스트가 실제로 적용되어 입력될 것이다. 만약 같은 상황에서 추천 후보를 더 보고 싶다면 <M-]>를, 다시 이전 추천으로 돌아가고 싶다면 <M-[>를 입력하면 된다. 그런데 개인적으로 이미 <tab>을 다른 auto completion 플러그인에 적용하여 사용중인데, 둘 다 <tab>으로 두고 쓰자니 오히려 불편해지는 감도 있고, (물론 copilot의 주장으로는 단축키 겹침으로 인한 불편함을 최소화하기 위해 추천하지 않을 때에는 기능대체가 되게끔 한다고 한다) 메타 키(alt 키)를 거의 사용하지 않는 편이라 다른 단축키들도 손에 잘 익지 않아 키맵을 바꿔 주었다. 사실 같은 상황에서 copilot의 여러 추천을 볼 수 있다는 것도 이 키맵 설정을 위해 이것저것 찾아보다 알게 된 기능이라, 의도치 않게 큰 이득을 봤다. 아무튼 원하는 새 키맵 역시 .vimrc에 추가해 주면, copilot 설정은 진짜로 끝이다.

아마 끝?

여기까지 왔으면, 아마 높은 확률로 아무 커맨드 에러 없이 아주 예쁘고 강력한 vim을 사용할 수 있을 것이다. 이를 완성하는 데 정말 많은 삽질을 했으나, 처음 이 포스트를 쓰기 시작할 때만 해도 그저 설움을 토로하기 위함이었는데 쓰다보니 준 튜토리얼급의 글을 적어버려 삽질 과정은 많이 생략하여 서술했다. 그래도 한 가지 꼭 기억해둘 삽질이 있기에 첨언해 두자면, coc.nvim의 핵심 기능 중 여러 경고 및 에러 메시지를 띄워주는 diagnostics를 포함하여 여러 리스트 창을 띄우는 기능들이 있는데, 이게 이상하게 원래 의도대로라면 작은 창으로 아래쪽에 떠서 esc만 눌러도 사라져야 하는데, 나 같은 경우 기존 버퍼를 다 덮어씌워 버려 끄지도 못하고 나가려면 :q!를 해야 하는 문제가 있었다. 원인을 찾기 위해 온갖 키워드(e.g. coc + diagnostics + fuzzy + …)들 을 넣어가며 구글링해보다가, 뭔가 다른 플러그인과의 충돌인 것 같아 길고 긴 .vimrc에서 각 설정 뭉치들을 주석하고, 주석을 풀어가며 기능이 언제 잘 작동하고 망가지는지 비교해 보는 짓을 해야만 했다. 그리고 찾은 원인은 NERDTree라는 플러그인. Neovim에서 :vs, :bo vs:sp, :bo sp 커맨드를 조금 더 스마트하게 사용하기 위해 거의 필수로 설치하고 설정해 두는 플러그인인데, 이 플러그인이 새로 열리는 임시 버퍼의 화면비크기를 마음대로 고정해 버리는 부분이 아마 문제였던 것 같다. 물론 조금만 더 잘 찾아보면 NERDTree와 coc.nvim을 함께 잘 사용할 방법이 있겠지만, 솔직히 이제는 :vs 커맨드를 쓰는 게 더 익숙해졌기에 미련없이 NERDTree 플러그인과 관련 설정 스크립트를 지워버렸다. 이젠 문제 없겠지.

새로운 시작

그렇게 해서 어찌저찌, 이번에는 정말 스크립트를 이해한 상태에서 여러 플러그인을 설치하고 세팅을 입맛대로 바꿔 보았다. 정말 많은 삽질과 고난이 있었지만, 대부분 마음 속에만 묻어 두기로 하고 나름 깔끔하게 포스트로 기록해 보았다. Vim아~ 이제 내 속 썩이지 말고 나랑 같이 오래오래 행복해야 한다~