초심자에게는 더 이상 추천되지 않는 설치 방법으로 neovim
이 처음이라면 LunarVim
을 통해 설치하기를 강력하게 권한다. 설치 방법은 다른 게시글에 자세히 정리해두었다.
vi
는 터미널에서 사용 가능한 리눅스의 텍스트 편집기 프로그램이다. 기본 기능 역시 훌륭하지만, 코드 에디터로 사용하기엔 부적절하다. 이번 글에서는 Neovim
을 설치하여 리눅스의 텍스트 에디터 프로그램을 VSCode
이상으로 더 쓸만하게 만들 예정이다.
Preview
위 그림은 변경 전의 vi
모습이고, 아래는 변경 후의 모습이다:
Neovim
설치클래식 vi
를 한단계 발전 시킨 프로그램이 vim
(Vi Improve
) 이라면, nvim
(neovim
) 은 여기에서 극강의 확장성을 추가한 프로그램이다.
다양한 플러그인 설치와 GUI
아키텍쳐 설계가 접목된 프로그램이다. vim
으로도 플러그인 설치는 가능하지만 Neovim
과 같은 확장성은 없다.
따라서 위에서 설명한 CoC
, Vim-Plug
, LSP
등의 플러그인과 다양한 vim
옵션 사용을 위해 neovim
을 설치하려 한다.
아래의 명령어를 입력하여 쉽게 설치할 수 있다:
sudo dnf install neovim
설치가 끝나면 nvim
을 입력하여 neovim
을 실행시킬 수 있다:
vim-plug
설치 가장 먼저 할 일은 vim-plug
의 설치이다. vim-plug
는 리눅스의 패키지 매니저와 같은 기능을 수행한다. 복잡하게 코드를 빌드하여 새로운 기능을 추가하는 것이 아닌, 패키지 이름만 입력하여 플러그인을 설치할 수 있다.
vim-plug
는 아래의 명령어를 입력하여 설치할 수 있다:
sh -c 'curl -fLo "${XDG_DATA_HOME:-$HOME/.local/share}"/nvim/site/autoload/plug.vim --create-dirs \ https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim'
내용이 좀 기니까 복사, 붙여넣기로 설치하길 바란다. 설치 후 nvim
설정 파일 최상단에 아래와 같은 내용을 기입한다:
" Plug-In 시작 (플러그인 설치 경로)
call plug#begin('~/.vim/plugged')
" 설치하고 싶은 플러그인 (예, NERDTree)
Plug 'preservim/nerdtree'
" 플러그인 시스템 초기화
call plug#end()
" 이하 본인의 nvim 설정
set nu
...
만약 nvim
이 처음이라면 nvim
설정 파일이 어디있는지, 또 어떻게 생성하는지 모를 수 있다.
nvim
설정 파일은 ~/.config/nvim/init.vim
에 존재한다. 설치 직후에는 nvim
경로도 없을 수 있으므로 아래의 명령어를 순서대로 입력하여 디렉터리와 파일을 생성한다.
mkdir ~/.config/nvim touch ~/.config/nvim/init.vim
이렇게 설정이 끝나면 vim-plug
를 쓸 수 있다. nvim
을 열고 :Plug<Tab>
을 입력시 아래와 같이 나오면 성공이다.
Plug-In
설치 vim-plug
의 최대 장점은 여러 사용자가 만든 플러그인을 쉽게 설치 가능하다는 것이다. 마음에 드는 플러그인을 찾았다면 설정 파일에 플러그인 이름 한줄만 작성하여 바로 설치할 수 있다.
플러그인 등록은 위에서 설명한 것처럼 진행하면 되고, 등록한 플러그인은 nvim
내에서 :PlugInstall
명령어를 입력하여 설치 가능하다.
위와 같이 :PlugInstall
을 입력하면 아래와 같이 설치된다.
설치할 수 있는 플러그인은 그 종류가 너무 많아서 일일이 다 설명할 순 없고, 필자가 주로 사용하는 플러그인들만 쭉 적어보겠다.
NERDTree
Plug 'preservim/nerdtree'
vim
내에서 소스트리를 확인하고, 쉽게 버퍼를 이동할 수 있게 만들어주는 플러그인이다.
왼쪽 상단의 창이 NERDTree
이다.
Tagbar
Plug 'preservim/tagbar'
현재 보고 있는 페이지의 class
, struct
, prototype
, typedef
, macro
등을 요약하여 표시한다.
좌측 하단의 창이 Tagbar
이다.
vim-airline
Plug 'vim-airline/vim-airline'
# Plug 'vim-airline/vim-airline-themes'
창 하단의 현재 버퍼 정보를 상세하게 표시한다. 추가적인 설정을 통해 상단에는 열린 버퍼와 탭들을 관리할 수 있다.
하단의 NORMAL
include/cjson.h
등의 정보가 바로 vim-airline
플러그인이 제공하는 기능이다. vim-airline
과 vim-airline-themes
를 제거하면 아래처럼 삭막하게 바뀐다.
ctrlp
<Ctrl> + p
를 눌러서 파일 탐색기(?) 를 열 수 있다. 창 하단에 간단한 파일 탐색 창이 나오는데, 원하는 파일 명의 일부를 입력하거나, <Ctrl> + j, k
를 이용하여 파일을 선택할 수 있다.
보통 NERDTree
는 파일 구성을 살피는 용도로 사용하고 실제 파일 버퍼 변경은 ctrlp
를 주로 사용한다. 매우 편리하다 : )
그 외에 필자가 사용하는 플러그인이 몇 개 더 있지만 이는 C
언어, Assembly
등 언어에 종속적이거나, vim
에 대한 세부사항을 알아야 쓸 수 있는 플러그인들이므로 설명을 생략했다.
CoC
(Conquer of Completion
) Coc
는 Conquer of Completion
의 약자로 실시간 자동 완성 기능을 지원해주는 플러그인이다.
기본적으로 vim
은 자동완성 기능을 지원해주지만 <Ctrl> + p
를 입력해야만 사용 가능한 목록들이 표시될뿐 타이핑 중에 나타내진 않는다.
또한 함수의 프로토타입, 매개변수 정보와 같은 세부사항도 나타나지 않는데, CoC
를 사용하면 이러한 모든 것들을 실시간
으로 표시해준다.
설치 방법이 아주 사알짝 복잡한데 아래 순서대로 따라하면 안 꼬인다:
Node.js
설치curl -sL install-node.now.sh/lts | sudo $SHELL
CoC 는 기본적으로 12.12 버전 이상의 NodeJS
를 필요로 한다. 왜 필요한진 모르겠는데 실시간 자동완성 쓰고 싶으면 군소리 말고 따라하길 바란다.
vim-plug
등록Plug 'neoclide/coc.nvim', {'branch': 'release'}
이제 다시 nvim
으로 돌아가 :PlugInstall
을 입력해 설치를 진행한다.
설치 후 다시 nvim
을 재시작한다. 아래와 같은 팝업이 뜬다면 제대로 설치가 완료된 것이다:
LSP
등록LSP
는 Language Server Protocol
의 약자로 IDE (Integrated development environment)
와 언어 서버 사이의 데이터 전송 통신규약(프로토콜)이다. 보통 자동 완성, 정의로 이동, 모든 참조 검색 등의 기능을 제공한다. 여기에서 필자는 LSP
의 자동 완성 기능과 참조 기능 등을 활용할 것이다.
위에서 제대로 CoC
플러그인이 설치되었다면, nvim
으로 들어가 아래의 명령어를 입력한다.
:CocInstall <LSP 서버명>
LSP
서버는 다음을 통해 확인하길 바란다.
필자는 C
언어를 사용하기 때문에 아래와 같이 입력하여 C
언어 서버를 설치할 것이다.
명령어 입력 시 왼쪽에 새로운 버퍼가 생성되고 여기에서 진행 상황이 보이게 된다. 설치 완료 시 아래와 같이 나오게 된다.
clangd
가 설치되어 있지 않다면 아래와 같은 팝업창이 나오는데 알려주는대로 설치하면 된다.
:CocCommand clangd.install
을 입력하여 설치를 진행한다.
설치가 끝났다면 :CocCommand clangd.update
명령어를 입력해서 실제 실행결과를 확인해보자.
Great!
nvim-treesitter
아직 끝이 아니다. nvim-treesitter
를 화룡정점으로 남겨놨다. nvim-treesitter
는 구문을 파싱하여 더 세부적인 하이라이팅을 제공한다.
해당 이미지는 nvim-treesitter
의 github
의 올라온 비교 이미지이다. C++
로 작성된 코드인데 왼쪽이 nvim-treesitter
적용 전, 오른쪽이 적용 후의 모습이다. 확연히 차이가 난다.
프로젝트가 커졌을 때는 식별자의 색상이 특히 더 중요한데, 이 treesitter
는 식별자의 타입별로 서로 다른 색상을 지정해서 더욱 가독성을 높여준다.
다음의 라인을 init.vim
에 추가한다:
Plug 'nvim-treesitter/nvim-treesitter', {'do': ':TSUpdate'}
파일 경로나 설치 방법 등은 위에서 죽도록 설명했으므로 생략하겠다.
플러그인 설치가 끝나면 사용하는 언어를 등록해야 한다. 필자는 C 언어를 사용할 것이므로 C 를 등록할 예정이다. 사용 가능한 언어들은 다음의 사이트에서 확인 가능하므로 독자들이 사용하는 언어를 찾아서 등록하길 바란다.
nvim
내에서 아래의 명령어를 입력하면 자동으로 설치가 진행된다.
:TSInstall <사용하는 언어>
설치 중 다음과 같은 에러가 발생할 수도 있다:
그럼 아래의 명령어를 입력해서 관련 패키지를 설치하길 바란다:
sudo dnf install libstdc++-static
마지막으로 플러그인 하이라이팅 설정만 손보면 된다.
nvim-treesitter
는 다양한 설정을 제공하지만, 귀찮다면 아래의 설정을 복사해서 init.vim
에 붙여 넣어도 된다.
lua <<EOF require'nvim-treesitter.configs'.setup { ensure_installed = "maintained", -- one of "all", "maintained" (parsers with maintainers), or a list of languages ignore_install = { "" }, -- List of parsers to ignore installing highlight = { enable = true, -- false will disable the whole extension disable = { "" }, -- list of language that will be disabled -- Setting this to true will run `:h syntax` and tree-sitter at the same time. -- Set this to `true` if you depend on 'syntax' being enabled (like for indentation). -- Using this option may slow down your editor, and you may see some duplicate highlights. -- Instead of true it can also be a list of languages additional_vim_regex_highlighting = false, }, } EOF
더 자세한 사항은 공식 github
을 참조하길 바란다.
설정 파일 수정 후, 파서 설치 중 아래와 같은 에러가 발생할 수 있다:
그럼 다음의 패키지를 다시 설치하고, 이어서 진행하면 된다.
sudo dnf install gcc-c++
정상적으로 설치가 완료되었다.
아래의 내용은 현재(Oct 15, 21
) 필자가 사용하는 nvim
의 설정파일이다. 각 라인마다 세부적인 주석을 달아놨으므로 참고해서, 독자들의 입맛에 맞게 수정하여 쓰길 바란다.
" =========================================================================
" = 플러그인 설정 =
" =========================================================================
call plug#begin('~/.vim/plugged') " 플러그인 시작
" Conquer Of Completion 자동완성 플러그인
Plug 'neoclide/coc.nvim', {'branch': 'release'}
" nvim-treesitter 구문 파싱 하이라이팅
Plug 'nvim-treesitter/nvim-treesitter', {'do': ':TSUpdate'}
" Tagbar 코드 뷰어 창
" Plug 'majutsushi/tagbar'
Plug 'preservim/tagbar'
" NERDTree 코드 뷰어 창
Plug 'preservim/nerdtree'
" 컬러스킴(색상표) jellybeans, gruvbox
Plug 'nanotech/jellybeans.vim'
" Plug 'morhetz/gruvbox'
" 하단에 다양한 상태(몇 번째 줄, 인코딩, etc.)를
" 표시하는 상태바 추가
Plug 'vim-airline/vim-airline'
Plug 'vim-airline/vim-airline-themes'
" CScope 플러그인
Plug 'ronakg/quickr-cscope.vim'
" CtrlP 파일 탐색 플러그인
Plug 'ctrlpvim/ctrlp.vim'
" 비활성 윈도우 강조
" Plug 'blueyed/vim-diminactive'
" vim cutlass 잘라내기 명령어가 yank 에 영향을 주지 않음
Plug 'svermeulen/vim-cutlass'
" VIM GAS(GNU ASsembler) Highlighting
Plug 'Shirk/vim-gas'
call plug#end()
" =========================================================================
" = 단축키 지정 =
" = n(normal mode) 명령 모드 =
" = v(visual, select mode) 비주얼 모드 =
" = x(visual mode only) 비주얼 모드 =
" = s(select mode only) 선택 모드 =
" = i(insert mode) 편집 모드 =
" = t(terminal mode) 편집 모드 =
" = c(commnad-line) 모드 =
" = re(recursive) 맵핑 =
" = nore(no recursive) 맵핑 =
" =========================================================================
" ------------------------------------
" 편집 모드
" ------------------------------------
" jk 와 kj 를 <ESC> 키로 맵핑
inoremap jk <ESC>
inoremap kj <ESC>
" ------------------------------------
" 명령 모드
" ------------------------------------
" <F1> 을 통해 NERDTree 와 Tagbar 열기
nnoremap <silent><F1> :NERDTreeToggle<CR><bar>:TagbarToggle <CR>
" <Ctrl + h, l> 를 눌러서 이전, 다음 탭으로 이동
nnoremap <silent><C-j> :tabprevious<CR>
nnoremap <silent><C-k> :tabnext<CR>
" <Ctrl + j, k> 를 눌러서 이전, 다음 버퍼로 전환
nnoremap <silent><C-h> :bp<CR>
nnoremap <silent><C-l> :bn<CR>
" <Shift + h, l> 를 눌러서 현재 버퍼 삭제
nnoremap <silent><S-h> :bp<bar>sp<bar>bn<bar>bd<CR>
nnoremap <silent><S-l> :bp<bar>sp<bar>bn<bar>bd<CR>
" <Ctrl + w> t 를 눌러서 커서를 NERDTree 로 옮기기
nnoremap <silent><C-w>t :NERDTreeFocus<CR>
" 우측 하단(botright)에 창 생성(new), 해당 창을 terminal 로 변경
" 크기를 10 으로 재설정(resize) 후 창 높이를 고정(winfixheight)시킴
" 줄번호는 삭제하고, 터미널 디렉터리 글자색을 변경
nnoremap <silent><F2>
\:botright new<CR><bar>
\:terminal<CR><bar><ESC>
\:resize 10<CR><bar>
\:set winfixheight<CR><bar>
\:set nonu<CR><bar>
\iLS_COLORS=$LS_COLORS:'di=1;33:ln=36'<CR>
" ------------------------------------
" 터미널 모드
" ------------------------------------
" 터미널 모드에서 <Ctrl + w> 누르면 명령 모드로 전환하고 <Ctrl + w> 입력
tmap <silent><C-w> <ESC><C-w>
" jk 혹은 kj 를 누르면 <ESC> 를 실행
tmap <silent>jk <ESC>
tmap <silent>kj <ESC>
" <ESC> 입력 시 <C-\><C-n> 실행 => 터미널 모드에서 기본 모드로 전환
tnoremap <silent><ESC> <C-\><C-n>
" ------------------------------------
" 명령, 비주얼 모드
" ------------------------------------
" iamroot 자동 주석
map <F9> <ESC>o/*<CR> * IAMROOT, <C-R>=strftime("%Y.%m.%d")<CR>
\: <CR>*/<CR><ESC><UP><UP><END>
" =========================================================================
" = vim 설정 =
" =========================================================================
" 탭 정지 = 8 칸마다
set tabstop=8
" 쉬프트 (<< 혹은 >>) 이동거리 8 칸
set shiftwidth=8
" 줄 번호를 표시한다.
set number
" 괄호 짝을 강조한다.
set showmatch
" 하위 디렉터리를 모두 path 에 추가한다.
" gf 명령어 사용 시 파일을 인식 가능
set path+=**
" 탐색 문자열 강조
set hlsearch
" 항상 상단에 탭 라인을 출력한다.
set showtabline=2
" 행 표시선 출력
set colorcolumn=80
if has('nvim') " nvim 을 사용 중이라면
set inccommand=nosplit " nvim live %s substitute (실시간 강조)
endif
" vim 과 OS 의 클립보드 동기화
set clipboard=unnamedplus
" GUI-Color 를 사용 가능하도록 설정 (TrueColor)
" cterm 혹은 term 대신 gui 를 통해 색상을 설정할 수 있고
" 16,777,216 종류의 색상 표현 가능(기존 256)
set termguicolors
" 모든 마우스 기능을 사용
set mouse=a
" mkview 명령어가 저장하는 요소 중
" 하나인 `options` 를 제거
set viewoptions-=options
" 문법이 존재하면
if has("syntax")
" 문법 강조를 수행
syntax on
endif
" 컬러스킴(문법 강조 색상) - 현재 jellybeans
colorschem jellybeans
" colorschem gruvbox
" =========================================================================
" = 하이라이트 정의 =
" =========================================================================
" 버퍼(창)과 버퍼의 끝(창의 끝)을 투명하게
highlight Normal guibg=NONE
highlight EndOfBuffer guibg=NONE
" 줄번호 배경색은 투명(NULL)하게,
" 글자는 굵게(bold), 글자색은 하얗게(White)
highlight LineNr guibg=NONE gui=bold guifg=white
" 행 표시선 색상
highlight ColorColumn guibg=White
" =========================================================================
" = 함수 정의 =
" =========================================================================
" tabsize 를 size 로 변경
function SetTab(size)
execute "set shiftwidth=".a:size
execute "set tabstop=".a:size
execute "set softtabstop=".a:size
endfunction
" =========================================================================
" = 자동 실행 (autocmd) =
" =========================================================================
" terminal buffer 에 진입했을 때 mode 를 normal 에서 terminal 모드로 변경
" 또한 줄번호를 없앤다.
autocmd BufEnter term://* start " do nothing
autocmd TermOpen term://* execute ":set nonu"
" 파일 명이 *.S 로 시작하면 GAS 문법 강조 사용
autocmd BufRead,BufNew *.S execute ":set ft=gas"
" 버퍼를 저장할때 파일 이름이 .c, .h 와 같다면 ctags 명령어를 실행
" autocmd BufWritePost *.c,*.h silent! !ctags -R &
" 윈도우를 나갈 때 뷰를 저장하고,
autocmd BufWinLeave *.c,*.h mkview
" 윈도우에 들어갈 땐 뷰를 로드한다. (커서위치 저장)
" silent! 는 loadview 중 발생하는 에러를 억압(suppress) 한다.
autocmd BufWinEnter *.c,*.h silent! loadview
" 활성화된 버퍼만 라인 번호 표시 (단, 확장자는 .c 혹은 .h 일때만 동작)
autocmd BufEnter * if (&filetype == 'c' || &filetype == 'cpp')
\| set number
\| endif
" 버퍼에서 나갈 땐 줄 번호를 지운다.
autocmd BufLeave * if (&filetype == 'c' || &filetype == 'cpp')
\| set nonumber
\| endif
" =========================================================================
" = 플러그인 설정 =
" =========================================================================
" ------------------------------------
" coc 설정
" ------------------------------------
" nvim 버전이 0.5.0 이상이며, 패치가 8.1.1564 이상이라면
if has("nvim-0.5.0") || has("patch-8.1.1564")
" 사인(sign column) 열을 숫자 열과 합침
set signcolumn=number
endif
" <Tab> 을 눌러서 현재 지시자를 옮김.
" inoremap <silent><expr> <TAB>
"\ pumvisible() ? "\<C-n>" :
"\ <SID>check_back_space() ? "\<TAB>" :
"\ coc#refresh()
"inoremap <expr><S-TAB> pumvisible() ? "\<C-p>" : "\<C-h>"
" <Backspace> 키가 지시자 제거, 기존 자동완성 양식 폐기
function! s:check_back_space() abort
let col = col('.') - 1
return !col || getline('.')[col - 1] =~# '\s'
endfunction
" <Ctrl + Space> 를 눌러서 자동완성 적용
if has('nvim')
inoremap <silent><expr> <c-space> coc#refresh()
else
inoremap <silent><expr> <c-@> coc#refresh()
endif
" 코드 탐색 단축키
nmap <silent> gr <Plug>(coc-references)
" 커서 아래의 토큰을 강조
autocmd CursorHold * silent call CocActionAsync('highlight')
" ------------------------------------
" nvim-treesitter 설정
" ------------------------------------
lua <<EOF
require'nvim-treesitter.configs'.setup {
ensure_installed = "maintained",
ignore_install = { "" },
highlight = {
enable = true,
disable = { "" },
additional_vim_regex_highlighting = true,
},
}
EOF
" ------------------------------------
" tagbar 설정
" ------------------------------------
" tagbar 생성 시 우측 하단에 위치하게끔 생성
let g:tagbar_position = 'rightbelow'
" ------------------------------------
" ConqueTerm 설정
" 창 전환 시 ConqueTerm 에 Insert 상태로 활성화
" let g:ConqueTerm_InsertOnEnter = 1
" ConqueTerm 이 Insert 모드인 상태에서도 <Ctrl>+w, W 를 사용 가능하게
" let g:ConqueTerm_CWInsert = 1
" ------------------------------------
" vim-airline 설정
" ------------------------------------
" powerline-font 활성화
let g:airline_powerline_fonts = 1
" luna 테마 사용
let g:airline_theme = 'luna'
" tabline 에 파일명만 출력 되도록 설정
let g:airline#extensions#tabline#formatter = 'unique_tail'
" 창의 상단에 표시되도록 설정
" let g:airline_statusline_ontop = 1
" 탭라인 허용
let g:airline#extensions#tabline#enabled = 1
" 항상 tabline 을 표시
let g:airline#extensions#tabline#show_tabs = 1
" ------------------------------------
" NERDTree 설정
" ------------------------------------
" 창 크기(가로)를 20 으로 설정
let g:NERDTreeWinSize=30
" ------------------------------------
" vim-cutlass 설정
" ------------------------------------
" c, C 명령어는 yank 에 영향을 주도록 변경
nnoremap c d
xnoremap c d
nnoremap cc dd
nnoremap C Dv
[사이트] https://github.com/neovim/neovim
[사이트] http://www.differencebetween.net/technology/difference-between-vim-and-neovim/
[사이트] https://github.com/junegunn/vim-plug
[이미지] https://github.com/neoclide/coc.nvim
[사이트, 이미지] https://github.com/nvim-treesitter/nvim-treesitter
이번에 처음으로 리눅스 사용해 보려다 유입됐습니다. 위의 nvim 설정 파일 내용을 사용했는데 Tab으로 자동 완성이 안 되네요. 혹시 "'Tab을 눌러서 현재 지시자를 옮김" 이 부분에서 설정을 해준 것 같은데 해결하는 방법이 있을까요? 양질의 글 감사합니다.
저는 devaslife 라는 일본 유튜버 보고 설정했던 기억이 나네요.
요즘은 한줄로 풀세팅되는 lunarvim 사용하고 있지만, 직접 설정하는거 재밌죠 ㅎㅎ
node 설치할때 plug 등록에서
Plug 'neoclide/coc.nvim', {'branch', 'release'} 이렇게 되어 있는데
Plug 'neoclide/coc.nvim', {'branch' : 'release'} 이렇게 해주니까 되네요.
도움이 많이 되었습니다. 감사합니다.
Error detected while processing /home/code/.vim/plugged/auto-pairs/plugin/auto-pairs.vim:
line 9:
E492: Not an editor command: ^M
line 10:
E15: Invalid expression: exists('g:AutoPairsLoaded') || &cp^M
line 674:
E171: Missing :endif
Press ENTER or type command to continue
플러그인 설치 했더니 계속 이런 오류가 뜨는데
해결 방법이 있을까요?
정말 neovim 설정에 큰 도움이 되었습니다~
감사합니다!