Neovim+Coc.nvim配置 目前個人最舒服終端編輯環境(Python&C++)


1. 前言

目前最常用的環境還是linux的服務器,所以最終選擇的是nvim作為自己的首要編輯器,畢竟沒有寫一些比較大型的項目。在經過多次的摸索后,我還是選擇了Neovim + Coc.nvim,放棄了 YCM。

在文章的最后,有完整的init.vim文件,這個文件是我目前正在使用的,相對於文中的部分有變動。本文希望在你學習和使用vim的過程中,幫助你熟悉相關的環境配置。

這里假設在沒有root權限的情況,考慮的是軟件的源碼安裝(相比之下,直接用各個發行版的命令安裝會更加簡單)。

2.Neovim 和插件安裝

2.1 Neovim 安裝

neovim:下載地址

選擇最新的release 的版本,

這里除了source code 是源碼外,其他的都是編譯好的,直接

wget https://github.com/neovim/neovim/releases/download/v0.4.3/nvim-linux64.tar.gz
tar -zxvf nvim-linux64.tar.gz

然后把neovim路徑下的bin加入到~/.bashrc,然后在source一下就算是成功了。

2.2 插件安裝

1. Vim-Plug

vim-plug是一個我很喜歡的vim的插件管理工具,使用下面的命令可以進行安裝(其他平台和工具的安裝方法地址中有):

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'

這樣,這個 ~/.local/share/nvim/site/autoload/plug.vim就會在你的目錄下,並且vim會被調用。

創建nvim的配置文件(這個配置文件和vim的'.vimrc')一樣:

mkdir ~/.config/nvim/
nvim ~/.config/nvim/init.vim

然后把

call plug#begin('~/.vim/plugged')
call plug#end()

加入到init.vim中,這樣以后在call begin和call end 之間加上插件就可以使用了。

之后的每個插件在init.vim文件中配置好后,要進行保存退出,再次進入nvim,使用命令 :PlugInstall安裝

2. indentLine

indentLine此插件提供的一個可視化的縮進,把Plug 'Yggdroot/indentLine',放到init.vim的call begin和call end之間,同時加入一些簡單的配置:

let g:indent_guides_guide_size            = 1  " 指定對齊線的尺寸
let g:indent_guides_start_level           = 2  " 從第二層開始可視化顯示縮進

效果如圖:

3. vim-monokai

vim-monokai,這個插件是nvim的一個主題,monokai這個配色是我最喜歡的,從開始用sublime的時候我一直都用的是這個主題。

在 call begin 和 call end 之間加上Plug 'crusoexia/vim-monokai',然后把

colo monokai

加到后面。

效果:

4.vim-airline

vim-airline給nvim 提供一個強大的狀態欄和標簽欄,當打開多個文本時,可以用它進行快速的切換,是一個很強大的工具。

在 call begin 和 call end 之間加上:

Plug 'vim-airline/vim-airline'       
Plug 'vim-airline/vim-airline-themes' "airline 的主題

然后在init.vim里加上一些個性的配置:

" 設置狀態欄
let g:airline#extensions#tabline#enabled = 1
let g:airline#extensions#tabline#left_alt_sep = '|'
let g:airline#extensions#tabline#buffer_nr_show = 0
let g:airline#extensions#tabline#formatter = 'default'
let g:airline_theme = 'desertink'  " 主題
let g:airline#extensions#keymap#enabled = 1
let g:airline#extensions#tabline#buffer_idx_mode = 1
let g:airline#extensions#tabline#buffer_idx_format = {
       \ '0': '0 ',
       \ '1': '1 ',
       \ '2': '2 ',
       \ '3': '3 ',
       \ '4': '4 ',
       \ '5': '5 ',
       \ '6': '6 ',
       \ '7': '7 ',
       \ '8': '8 ',
       \ '9': '9 '
       \}
" 設置切換tab的快捷鍵 <\> + <i> 切換到第i個 tab
nmap <leader>1 <Plug>AirlineSelectTab1
nmap <leader>2 <Plug>AirlineSelectTab2
nmap <leader>3 <Plug>AirlineSelectTab3
nmap <leader>4 <Plug>AirlineSelectTab4
nmap <leader>5 <Plug>AirlineSelectTab5
nmap <leader>6 <Plug>AirlineSelectTab6
nmap <leader>7 <Plug>AirlineSelectTab7
nmap <leader>8 <Plug>AirlineSelectTab8
nmap <leader>9 <Plug>AirlineSelectTab9
" 設置切換tab的快捷鍵 <\> + <-> 切換到前一個 tab
nmap <leader>- <Plug>AirlineSelectPrevTab
" 設置切換tab的快捷鍵 <\> + <+> 切換到后一個 tab
nmap <leader>+ <Plug>AirlineSelectNextTab
" 設置切換tab的快捷鍵 <\> + <q> 退出當前的 tab
nmap <leader>q :bp<cr>:bd #<cr>
" 修改了一些個人不喜歡的字符
if !exists('g:airline_symbols')
    let g:airline_symbols = {}
endif
let g:airline_symbols.linenr = "CL" " current line
let g:airline_symbols.whitespace = '|'
let g:airline_symbols.maxlinenr = 'Ml' "maxline
let g:airline_symbols.branch = 'BR'
let g:airline_symbols.readonly = "RO"
let g:airline_symbols.dirty = "DT"
let g:airline_symbols.crypt = "CR" 

效果為:

5. nerdcommenter

nerdcommenter是一個很好用的注釋工具,在normal和visual模式下,他會對你光標所在行或所選中的多行進行注釋和去注釋,只需要你按下 <\>+<c>+<space>。

在 call begin 和 call end 之間加上Plug 'scrooloose/nerdcommenter',在進行簡單的配置

"add spaces after comment delimiters by default
let g:NERDSpaceDelims = 1
" python 自動的會多加一個空格
au FileType python let g:NERDSpaceDelims = 0

" Use compact syntax for prettified multi-line comments
let g:NERDCompactSexyComs = 1

" Align line-wise comment delimiters flush left instead of following code indentation
let g:NERDDefaultAlign = 'left'

" Set a language to use its alternate delimiters by default
let g:NERDAltDelims_java = 1

" Add your own custom formats or override the defaults
" let g:NERDCustomDelimiters = { 'c': { 'left': '/**','right': '*/' } }

" Allow commenting and inverting empty lines (useful when commenting a region)
let g:NERDCommentEmptyLines = 1

" Enable trimming of trailing whitespace when uncommenting
let g:NERDTrimTrailingWhitespace = 1

" Enable NERDCommenterToggle to check all selected lines is commented or not
let g:NERDToggleCheckAllLines = 1

6. rainbow

rainbow是一個提供嵌套括號高亮的一個工具。

在 call begin 和 call end 之間加上Plug 'luochen1990/rainbow'
我對括號的顏色進行了簡單的修改:

let g:rainbow_active = 1
let g:rainbow_conf = {
\   'guifgs': ['darkorange3', 'seagreen3', 'royalblue3', 'firebrick'],
\   'ctermfgs': ['lightyellow', 'lightcyan','lightblue', 'lightmagenta'],
\   'operators': '_,_',
\   'parentheses': ['start=/(/ end=/)/ fold', 'start=/\[/ end=/\]/ fold', 'start=/{/ end=/}/ fold'],
\   'separately': {
\       '*': {},
\       'tex': {
\           'parentheses': ['start=/(/ end=/)/', 'start=/\[/ end=/\]/'],
\       },
\       'lisp': {
\           'guifgs': ['darkorange3', 'seagreen3', 'royalblue3', 'firebrick'],
\       },
\       'vim': {
\           'parentheses': ['start=/(/ end=/)/', 'start=/\[/ end=/\]/', 'start=/{/ end=/}/ fold', 'start=/(/ end=/)/ containedin=vimFuncBody', 'start=/\[/ end=/\]/ containedin=vimFuncBody', 'start=/{/ end=/}/ fold containedin=vimFuncBody'],
\       },
\       'html': {
\           'parentheses': ['start=/\v\<((area|base|br|col|embed|hr|img|input|keygen|link|menuitem|meta|param|source|track|wbr)[ >])@!\z([-_:a-zA-Z0-9]+)(\s+[-_:a-zA-Z0-9]+(\=("[^"]*"|'."'".'[^'."'".']*'."'".'|[^ '."'".'"><=`]*))?)*\>/ end=#</\z1># fold'],
\       },
\       'css': 0,
\   }
\}

效果:

7. nerdtree

nerdtree是一個樹形的目錄管理插件,可以方便在nvim中進行當前文件夾中的文件切換

在 call begin 和 call end 之間加上

Plug 'preservim/nerdtree'
Plug 'Xuyuanp/nerdtree-git-plugin'

在 call begin 和 call end 之間加上'preservim/nerdtree'

進行以下的簡單配置

" autocmd vimenter * NERDTree  "自動開啟Nerdtree
let g:NERDTreeWinSize = 25 "設定 NERDTree 視窗大小
let NERDTreeShowBookmarks=1  " 開啟Nerdtree時自動顯示Bookmarks
"打開vim時如果沒有文件自動打開NERDTree
" autocmd vimenter * if !argc()|NERDTree|endif
"當NERDTree為剩下的唯一窗口時自動關閉
autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTree") && b:NERDTree.isTabTree()) | q | endif
" 設置樹的顯示圖標
let g:NERDTreeDirArrowExpandable = '+'
let g:NERDTreeDirArrowCollapsible = '-'
let NERDTreeIgnore = ['\.pyc$']  " 過濾所有.pyc文件不顯示
let g:NERDTreeShowLineNumbers=0 " 是否顯示行號
let g:NERDTreeHidden=0     "不顯示隱藏文件
""Making it prettier
let NERDTreeMinimalUI = 1
let NERDTreeDirArrows = 1
nnoremap <F3> :NERDTreeToggle<CR> " 開啟/關閉nerdtree快捷鍵

默認的情況下是關閉的,可以把autocmd vimenter * NERDTree的注釋打開,改成默認開啟的狀態。同時把開關的按鍵映射到了F3,按下可以打開或關閉。

效果:

8. tagbar

tagbar可以用來展示當前的文件的一些函數。

這個插件依賴ctags,需要先安裝ctags。從官網下載源碼,進行編譯(如果有root權限直接安裝,跳過源碼編譯)。

wget http://prdownloads.sourceforge.net/ctags/ctags-5.8.tar.gz
tar -zxvf ctags-5.8.tar.gz
cd ctags-5.8
./configure --prefix=$PATH # $PATH是你要安裝的位置
make -j
make install

然后把安裝目錄里的bin所在的路徑加到~/.bashrc中,在source一下,輸入命令ctags,如果輸出

ctags: No files specified. Try "ctags --help". 

那ctags就安裝成功了。

然后在init.vim中的call begin和call end 之間加入Plug 'majutsushi/tagbar',我這里還設置了tagbar的寬度和按鍵映射,這樣可以通過F4方便的進行打開和關上。在tagbar窗口可以按下回車跳轉到指定的函數。

let g:tagbar_width=30
nnoremap <silent> <F4> :TagbarToggle<CR> " 將tagbar的開關按鍵設置為 F4

9. vim-cpp-enhanced-highlight

vim-cpp-enhanced-highlight,這個是用來加強C++的高亮的,很少用C++,沒仔細看

Plug 'octol/vim-cpp-enhanced-highlight'

10. vim-snippets

honza/vim-snippets我用來提供C++的snippets,python 那邊使用的coc.nvim提供的,感覺這個東西挺復雜的,也沒咋看,但是能用就行。

Plug 'honza/vim-snippets'

11. coc.nvim

coc.nvim是目前我用過的最舒服的、集代碼補全、靜態檢測、函數跳轉等功能的一個引擎,強力推薦!!!

安裝coc.nvim,需要安裝nodejs。和nvim一樣,這個也有編譯好的版本,解壓后把bin的路徑放到放到.bashrc里,之后運行

npm install -g neovim

安裝

Plug 'neoclide/coc.nvim', {'branch': 'release'}

注意的是,低版本的git會在后面進行更新coc.nvim插件的時候報錯,報的啥我也忘了,反正如果更新的時候發現有git的錯誤,升級一下git就行了。

下面的設置是在他的主頁上參考的。

" if hidden is not set, TextEdit might fail.
set hidden
" Some servers have issues with backup files, see #649
set nobackup
set nowritebackup

" You will have bad experience for diagnostic messages when it's default 4000.
set updatetime=300

" don't give |ins-completion-menu| messages.
set shortmess+=c

" always show signcolumns
set signcolumn=yes

" Use tab for trigger completion with characters ahead and navigate.
" Use command ':verbose imap <tab>' to make sure tab is not mapped by other plugin.
inoremap <silent><expr> <TAB>
      \ pumvisible() ? "\<C-n>" :
      \ <SID>check_back_space() ? "\<TAB>" :
      \ coc#refresh()
inoremap <expr><S-TAB> pumvisible() ? "\<C-p>" : "\<C-h>"

function! s:check_back_space() abort
  let col = col('.') - 1
  return !col || getline('.')[col - 1]  =~# '\s'
endfunction

" Use <c-space> to trigger completion.
inoremap <silent><expr> <c-space> coc#refresh()

" Use <cr> to confirm completion, `<C-g>u` means break undo chain at current position.
" Coc only does snippet and additional edit on confirm.
inoremap <expr> <cr> pumvisible() ? "\<C-y>" : "\<C-g>u\<CR>"
" Or use `complete_info` if your vim support it, like:
" inoremap <expr> <cr> complete_info()["selected"] != "-1" ? "\<C-y>" : "\<C-g>u\<CR>"

" Use `[g` and `]g` to navigate diagnostics
nmap <silent> [g <Plug>(coc-diagnostic-prev)
nmap <silent> ]g <Plug>(coc-diagnostic-next)
" Remap keys for gotos
nmap <silent> gd <Plug>(coc-definition)
nmap <silent> gy <Plug>(coc-type-definition)
nmap <silent> gi <Plug>(coc-implementation)
nmap <silent> gr <Plug>(coc-references)

" Use K to show documentation in preview window
nnoremap <silent> K :call <SID>show_documentation()<CR>

function! s:show_documentation()
  if (index(['vim','help'], &filetype) >= 0)
    execute 'h '.expand('<cword>')
  else
    call CocAction('doHover')
  endif
endfunction

" Highlight symbol under cursor on CursorHold
autocmd CursorHold * silent call CocActionAsync('highlight')

" Remap for rename current word
nmap <leader>rn <Plug>(coc-rename)

" Remap for format selected region
xmap <leader>f  <Plug>(coc-format-selected)
nmap <leader>f  <Plug>(coc-format-selected)

augroup mygroup
  autocmd!
  " Setup formatexpr specified filetype(s).
  autocmd FileType typescript,json setl formatexpr=CocAction('formatSelected')
  " Update signature help on jump placeholder
  autocmd User CocJumpPlaceholder call CocActionAsync('showSignatureHelp')
augroup end

" Remap for do codeAction of selected region, ex: `<leader>aap` for current paragraph
xmap <leader>a  <Plug>(coc-codeaction-selected)
nmap <leader>a  <Plug>(coc-codeaction-selected)

" Remap for do codeAction of current line
nmap <leader>ac  <Plug>(coc-codeaction)
" Fix autofix problem of current line
nmap <leader>qf  <Plug>(coc-fix-current)

" Create mappings for function text object, requires document symbols feature of languageserver.
xmap if <Plug>(coc-funcobj-i)
xmap af <Plug>(coc-funcobj-a)
omap if <Plug>(coc-funcobj-i)
omap af <Plug>(coc-funcobj-a)

" Use `:Format` to format current buffer
command! -nargs=0 Format :call CocAction('format')

" Use `:Fold` to fold current buffer
command! -nargs=? Fold :call     CocAction('fold', <f-args>)

" use `:OR` for organize import of current buffer
command! -nargs=0 OR   :call     CocAction('runCommand', 'editor.action.organizeImport')

這樣,coc.nvim 平台安裝完成了,此外,為了提高多種功能,還要進行相關插件的安裝,這個放到后面的環境配置里。

12. nvim的基本配置

filetype plugin on
" 設置為雙字寬顯示,否則無法完整顯示如:☆
" set ambiwidth=double
set t_ut= " 防止vim背景顏色錯誤
set showmatch " 高亮匹配括號
set matchtime=1
set report=0
set ignorecase
set nocompatible
set noeb
set softtabstop=4
set shiftwidth=4
set nobackup
set autoread
set nocompatible
set nu "設置顯示行號
set backspace=2 "能使用backspace回刪
syntax on "語法檢測
set ruler "顯示最后一行的狀態
set laststatus=2 "兩行狀態行+一行命令行
set ts=4
set expandtab
set autoindent "設置c語言自動對齊
set t_Co=256 "指定配色方案為256
" set mouse=a "設置可以在VIM使用鼠標
set selection=exclusive
" set selectmode=mouse,key
set tabstop=4 "設置TAB寬度
set history=1000 "設置歷史記錄條數   
" 配色方案
" let g:seoul256_background = 234
colo monokai
set background=dark
set shortmess=atl
" colorscheme desert
"共享剪切板
set clipboard+=unnamed 
set cmdheight=3
if version >= 603
     set helplang=cn
     set encoding=utf-8
endif
set fencs=utf-8,ucs-bom,shift-jis,gb18030,gbk,gb2312,cp936
set termencoding=utf-8
set encoding=utf-8
set fileencodings=ucs-bom,utf-8,cp936
set fileencoding=utf-8
set updatetime=300
set shortmess+=c
set signcolumn=yes

" autocmd FileType json syntax match Comment +\/\/.\+$+

set foldmethod=indent " 設置默認折疊方式為縮進
set foldlevelstart=99 " 每次打開文件時關閉折疊

" hi Normal ctermfg=252 ctermbg=none "背景透明
" au FileType gitcommit,gitrebase let g:gutentags_enabled=0
if has("autocmd")
    au BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g'\"" | endif
endif
inoremap jj <Esc> "將jj映射到Esc

3. Coc.nvim 環境配置

對於Python,直接裝anaconda就行了,同時需要用pip裝一下pynvim。

pip install pynvim

在nvim輸入:checkhealth,會進行基本環境的檢查,保證你用的環境不會出問題即可,我不用python2和ruby,這兩是warning就無所謂了。

上面的環境安裝結束后,並不能直接使用,還需要進一步的配置coc.nvim。
coc.nvim 提供了很多有用的擴展工具在coc extensions中,這些擴展在nvim中通過命令:CocInstall進行安裝,下面是我安裝的一個表:

:CocInstall coc-clangd  # C++環境插件
:CocInstall coc-cmake  # Cmake 支持
:CocInstall coc-emmet  
:CocInstall coc-git    # git 支持
:CocInstall coc-highlight  # 高亮支持
:CocInstall coc-jedi   # jedi
:CocInstall coc-json   # json 文件支持
:CocInstall coc-python # python 環境支持
:CocInstall coc-sh     # bash 環境支持
:CocInstall coc-snippets # python提供 snippets
:CocInstall coc-vimlsp # lsp
:CocInstall coc-yaml   # yaml
:CocInstall coc-syntax
:CocInstall coc-pairs

注意coc-python現在已經不在進行維護了,作者建議使用coc-pyright或者coc-jedi,具體可以參考coc-python
對於C++,本文按照clangd進行配置,原因是本人好久不用C++了,之前用的還是clangd。對於C++,coc.nvim支持clangd和ccls兩種方案,具體見:地址。如果需要使用ccls,可以參考他人的文章。
對於clangd,coc.nvim 會自動進行配置的,如果你沒有安裝clang的話,插件coc-clangd在你第一次打開C++文件時,會提示

[coc.nvim] clangd was not found on your PATH. :CocCommand clangd.install will install 10.0.0.

按照提示進行,如果不行的話,那只能去裝一個clang了,這里參考的是安裝 LLVM 和 Clang
如果你有root的權限,可以參考官方的的安裝方法更快捷的安裝:http://clangd.llvm.org/installation.html

mkdir llvm-source-build
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-9.0.1/llvm-9.0.1.src.tar.xz
tar xvf llvm-9.0.1.src.tar.xz
mv llvm-9.0.1.src llvm
cd llvm/tools/
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-9.0.1/clang-9.0.1.src.tar.xz
tar xvf clang-9.0.1.src.tar.xz
rm clang-9.0.1.src.tar.xz
mv clang-9.0.1.src clang
cd clang/tools/
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-9.0.1/clang-tools-extra-9.0.1.src.tar.xz
tar xvf clang-tools-extra-9.0.1.src.tar.xz
mv clang-tools-extra-9.0.1.src extra
rm clang-tools-extra-9.0.1.src.tar.xz
cd ../../../
mkdir build
cd build/
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DLLVM_TARGETS_TO_BUILD="X86" ../ -DCMAKE_INSTALL_PREFIX=$PATH # 改成你的安裝路徑
make -j
make install

測試一下clang和clangd兩個命令,檢查是否安裝成功。
對於Python的配置,安裝好coc-python就算是結束了,進入.py文件的話如果發現jedi報錯的話,重新安裝一下jedi即可,可能是jedi的版本太低。
最后,我把代碼檢測里的那個warning的符號改了, 本來是一個黃色的三角圖標,我擔心對終端不友好,改成了兩個嘆號。
coc.nvim的配置文件位置為:~/.config/nvim/coc-settings.json

{
  "diagnostic.warningSign":"!!"
}

這樣就都配置好了。
在snaipppts的提示中,可以通過 Ctrl + j 進行移動修改(從https://github.com/neoclide/coc-snippets弄來的,侵刪)

在函數里,可以通過按下gd進行函數的跳轉,ctrl + o 回調到上次的位置,效果如下圖:


最后放一下自己目前在用的init.vim(.vimrc)(和上面介紹的有改動):
(主題顏色配置基於windows terminal)init.vim/.vimrc

關注公眾號

免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2023 CODEPRJ.COM