太好用了!把Vim打造成一个好用的IDE

770 阅读6分钟

大家好,我是一名练习时长两年半的Vim练习生。最早用Vim写代码是为了装逼,但如今已完全离不开,真的太好用了!
好用在哪?
1.插件系统强大,可以把Vim定制成一个强大IDE。
2.命令丰富,写代码完全不用鼠标,很有操作感,提升效率。
3.运行在linux开发机上,随时随地ssh愉快写代码,不需要到处配开发环境。
操作.gif

话不多说,我以Centos7.6为例,跟大家探讨下如何把Vim打造成一个好用的IDE。

用Neovim替换Vim

Neovim相比于Vim确实有很多优点,我感受最深的两点:

  1. 更加丝滑。
  2. 有更好的配置默认值,默认会开启一些用户友好的特性。(后续如果有跟本文表现不一致可能是nvim和vim的默认特性导致)

以下是具体步骤:

1. 下载:

本文所有下载都会在一个自建的/user/local/soft目录下,下文提及的所有/user/local/soft都可以替换成你自己的目录。

wget https://github.com/neovim/neovim/releases/download/v0.8.3/nvim.appimage
2. 替换vim命令
chmod u+x nvim.appimage
mv /usr/bin/vim /usr/bin/vim7  # 作vim备份,要是执行不了,你可以先which vim查看一下
ln -s /usr/local/soft/nvim.appimage /usr/bin/vim
3. 创建nvim配置文件

vim的配置文件是~/.vimrc,nvim的配置在~/.config/nvim/init.vim,需要自己创建下。

mkdir -p ~/.config/nvim && touch ~/.config/nvim/init.vim

先在init.vim上测试下吧!
配上这两行,保存(:w)。

set nocompatible " 不兼容vi,这样可以发挥vim的很多强大功能。
set mouse="" " 禁鼠标,这个不禁vim右键会出一个弹窗,挺难受的。

vim插件管理

下载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'

在init.vim配置这两行,插件放这两行中间。

call plug#begin()
call plug#end()

比如我想用一个主题的插件,可以这么写:

call plug#begin()
Plug 'morhetz/gruvbox'
call plug#end()

" 每个插件都有对应的一些配置,这是主题相关的配置
colorscheme gruvbox
set background=dark

写完保存退出,再重新打开init.vim并输入:PlugInstall,就会开始下载插件了。(每次新加插件,都需要保存退出重启下vim)

1679830759985.png

下载完成。 1679830832607.png

再重启下Vim,就会看到Vim已经变样了。可以通过设置background来更换主题。 1ea3766a8bf061e1d3b55d98d585632.png

这里有个小问题,我的命令行是设了背景图片的,但用了主题后就没了...
配置这行即可。

autocmd vimenter * hi Normal guibg=NONE ctermbg=NONE " 背景透明

必用的插件

1. Nerdtree
Plug 'preservim/nerdtree'
nnoremap <C-n> :NERDTreeToggle<CR>
nnoremap <C-l> :NERDTreeFind<CR>

用来做目录管理。ctrl-n唤起目录。

1679831708837.png

2. Coc

这个是最核心的插件了,补全跳转全靠它,支持所有热门语言。
Coc依赖nodejs,需要先下载nodejs。

wget https://nodejs.org/dist/v14.14.0/node-v14.14.0-linux-x64.tar.gz
tar -xvf node-v14.14.0-linux-x64.tar.gz
ln -s /usr/local/soft/node-v14.14.0-linux-x64/bin/node /usr/bin/
ln -s /usr/local/soft/node-v14.14.0-linux-x64/bin/npm /usr/bin/
Plug 'neoclide/coc.nvim', {'branch': 'release'}

按tab切换补全建议。

# ~/.config/nvim/init.vim
inoremap <silent><expr> <TAB>
      \ coc#pum#visible() ? coc#pum#next(1) :
      \ CheckBackspace() ? "\<Tab>" :
      \ coc#refresh()
inoremap <expr><S-TAB> coc#pum#visible() ? coc#pum#prev(1) : "\<C-h>"

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

gd代码跳转,剩下几个命令都非常好用,经常用的到。

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)

coc也有自己的配置项,可以呈现不同的特性,在~/.config/nvim/coc-settings.json,也可通过:CocConfig唤起

:CocConfig

coc也为各种语言提供了集成插件,非常方便。 由于我目前是做go开发,我拿go来举例: 打开vim,输入

:CocInstall coc-go  

下载完成,来体验下吧。

补全.gif

体验调整

这节还是以go为举例,以上配置完成后,还是发现了几个问题。

  1. 没有高亮。
  2. 缩进好怪(好大一格)。
  3. 没有自动导入包。
  4. 没有自动Fomart。
    针对以上问题,可做如下配置。
# go代码高亮
let g:go_highlight_types = 1
let g:go_highlight_fields = 1
let g:go_highlight_functions = 1
let g:go_highlight_function_calls = 1
let g:go_highlight_extra_types = 1
let g:go_highlight_generate_tags = 1
# 缩进显示
set tabstop=4  " tab字符的显示长度=4个空格
set softtabstop=4 " tab字符的实际长度=4个空格
set expandtab " tab字符真实替换成4个空格
set shiftwidth=4  " 自动缩进的长度
# 自动导入包,自动fomrat
autocmd BufWritePre *.go :call CocAction('runCommand', 'editor.action.organizeImport')
autocmd BufWritePre *.go :call CocAction('format')

好用的插件

1. ale

由于coc的错误提示不够友好,可以用ale取代,非常好用。

Plug 'dense-analysis/ale'
let g:ale_set_highlights = 1
let g:ale_set_quickfix = 1
let g:ale_echo_msg_error_str = 'E'
let g:ale_echo_msg_warning_str = 'W'
let g:ale_echo_msg_format = '[%linter%] %s [%severity%]'
nmap sp <Plug>(ale_previous_wrap)
nmap sn <Plug>(ale_next_wrap)
nmap <Leader>d :ALEDetail<CR>
let g:ale_linters_ignore = {
\ 'go': ['golint'],
\ }

注: 由于ale的错误提示会和coc冲突需要在:CocConfig下配置

{
    "diagnostic.displayByAle" : true
}
2. vim-commentary

支持所有热门语言,选中后按gc可快速注释或取消注释

Plug 'tpope/vim-commentary'
3. vim-startify

vim启动页,可快速进入目标文件

Plug 'mhinz/vim-startify'
完整配置

~/.config/nvim/init.vim

set nocompatible " 不兼容vi

set mouse="" " 禁鼠标

set nu " 设置行号

set incsearch " 开启实时搜索
set hlsearch " 开启高亮搜索
set ignorecase " 搜索时大小写不敏感

syntax on " 高亮

set showcmd " 输入命令显示

filetype plugin indent on " 根据filetype作缩进

" Some servers have issues with backup files, see #649
set nobackup
set nowritebackup

call plug#begin()
Plug 'morhetz/gruvbox'
Plug 'preservim/nerdtree'
Plug 'neoclide/coc.nvim', {'branch': 'release'}
Plug 'dense-analysis/ale'
Plug 'tpope/vim-commentary'
Plug 'mhinz/vim-startify'
call plug#end()

" 主题
colorscheme gruvbox
set background=dark
autocmd vimenter * hi Normal guibg=NONE ctermbg=NONE " 背景透明

" Nerdtree
nnoremap <C-n> :NERDTreeToggle<CR>
nnoremap <C-l> :NERDTreeFind<CR>

" Coc
inoremap <silent><expr> <TAB>
      \ coc#pum#visible() ? coc#pum#next(1) :
      \ CheckBackspace() ? "\<Tab>" :
      \ coc#refresh()
inoremap <expr><S-TAB> coc#pum#visible() ? coc#pum#prev(1) : "\<C-h>"

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

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)

" 按K可以查函数文档
nnoremap <silent> K :call ShowDocumentation()<CR>
function! ShowDocumentation()
  if CocAction('hasProvider', 'hover')
    call CocActionAsync('doHover')
  else
    call feedkeys('K', 'in')
  endif
endfunction

" go代码高亮
let g:go_highlight_types = 1
let g:go_highlight_fields = 1
let g:go_highlight_functions = 1
let g:go_highlight_function_calls = 1
let g:go_highlight_extra_types = 1
let g:go_highlight_generate_tags = 1

" 缩进显示
set tabstop=4  " tab字符的显示长度=4个空格
set softtabstop=4 " tab字符的实际长度=4个空格
set expandtab " tab字符真实替换成4个空格
set shiftwidth=4  " 自动缩进的长度

" 自动导入包,自动fomrat
autocmd BufWritePre *.go :call CocAction('runCommand', 'editor.action.organizeImport')
autocmd BufWritePre *.go :call CocAction('format')

" ale
let g:ale_set_highlights = 1
let g:ale_set_quickfix = 1
let g:ale_echo_msg_error_str = 'E'
let g:ale_echo_msg_warning_str = 'W'
let g:ale_echo_msg_format = '[%linter%] %s [%severity%]'
nmap sp <Plug>(ale_previous_wrap)
nmap sn <Plug>(ale_next_wrap)
nmap <Leader>d :ALEDetail<CR>
let g:ale_linters_ignore = {
\ 'go': ['golint'],
\ }

" proto文件缩进设置
autocmd FileType proto set shiftwidth=2 | set expandtab | set tabstop=2 | set softtabstop=2

~/.config/nvim/coc-settings.json

{
    "suggest.noselect" : true,
    "diagnostic.displayByAle" : true
}

注:suggest.noselect是个人习惯,我喜欢补全初始状态为不选中,手感会比较好。

展示

操作.gif

结束语

由于篇幅,有些问题未能展开,Vim好用的插件远不止此。
另外本文都是用go来举例,实际上其他语言的配置一样很简单,我也用vim来写Python,Coc也有Python对应的插件。
赶紧动手来定制一个自己的Vim吧~